1/*
2 * Copyright (c) 2013-2015, The Linux Foundation. All rights reserved.
3
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
6 * met:
7 *   * Redistributions of source code must retain the above copyright
8 *     notice, this list of conditions and the following disclaimer.
9 *   * Redistributions in binary form must reproduce the above
10 *     copyright notice, this list of conditions and the following
11 *     disclaimer in the documentation and/or other materials provided
12 *     with the distribution.
13 *   * Neither the name of The Linux Foundation nor the names of its
14 *     contributors may be used to endorse or promote products derived
15 *     from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
18 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
20 * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
21 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
24 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
26 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
27 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30#define LOG_TAG "offload_effect_api"
31#define LOG_NDEBUG 0
32//#define VERY_VERY_VERBOSE_LOGGING
33#ifdef VERY_VERY_VERBOSE_LOGGING
34#define ALOGVV ALOGV
35#else
36#define ALOGVV(a...) do { } while(0)
37#endif
38
39#include <stdbool.h>
40#include <cutils/log.h>
41#include <tinyalsa/asoundlib.h>
42#include <sound/audio_effects.h>
43#include <errno.h>
44
45#include "effect_api.h"
46
47#define ARRAY_SIZE(array) (sizeof array / sizeof array[0])
48
49typedef enum eff_mode {
50    OFFLOAD,
51} eff_mode_t;
52
53#define OFFLOAD_PRESET_START_OFFSET_FOR_OPENSL 19
54const int map_eq_opensl_preset_2_offload_preset[] = {
55    OFFLOAD_PRESET_START_OFFSET_FOR_OPENSL,   /* Normal Preset */
56    OFFLOAD_PRESET_START_OFFSET_FOR_OPENSL+1, /* Classical Preset */
57    OFFLOAD_PRESET_START_OFFSET_FOR_OPENSL+2, /* Dance Preset */
58    OFFLOAD_PRESET_START_OFFSET_FOR_OPENSL+3, /* Flat Preset */
59    OFFLOAD_PRESET_START_OFFSET_FOR_OPENSL+4, /* Folk Preset */
60    OFFLOAD_PRESET_START_OFFSET_FOR_OPENSL+5, /* Heavy Metal Preset */
61    OFFLOAD_PRESET_START_OFFSET_FOR_OPENSL+6, /* Hip Hop Preset */
62    OFFLOAD_PRESET_START_OFFSET_FOR_OPENSL+7, /* Jazz Preset */
63    OFFLOAD_PRESET_START_OFFSET_FOR_OPENSL+8, /* Pop Preset */
64    OFFLOAD_PRESET_START_OFFSET_FOR_OPENSL+9, /* Rock Preset */
65    OFFLOAD_PRESET_START_OFFSET_FOR_OPENSL+10 /* FX Booster */
66};
67
68const int map_reverb_opensl_preset_2_offload_preset
69                  [NUM_OSL_REVERB_PRESETS_SUPPORTED][2] = {
70    {1, 15},
71    {2, 16},
72    {3, 17},
73    {4, 18},
74    {5, 3},
75    {6, 20}
76};
77
78int offload_update_mixer_and_effects_ctl(int card, int device_id,
79                                         struct mixer *mixer,
80                                         struct mixer_ctl *ctl)
81{
82    char mixer_string[128];
83
84    snprintf(mixer_string, sizeof(mixer_string),
85             "%s %d", "Audio Effects Config", device_id);
86    ALOGV("%s: mixer_string: %s", __func__, mixer_string);
87    mixer = mixer_open(card);
88    if (!mixer) {
89        ALOGE("Failed to open mixer");
90        ctl = NULL;
91        return -EINVAL;
92    } else {
93        ctl = mixer_get_ctl_by_name(mixer, mixer_string);
94        if (!ctl) {
95            ALOGE("mixer_get_ctl_by_name failed");
96            mixer_close(mixer);
97            mixer = NULL;
98            return -EINVAL;
99        }
100    }
101    ALOGV("mixer: %p, ctl: %p", mixer, ctl);
102    return 0;
103}
104
105void offload_close_mixer(struct mixer *mixer)
106{
107    mixer_close(mixer);
108}
109
110void offload_bassboost_set_device(struct bass_boost_params *bassboost,
111                                  uint32_t device)
112{
113    ALOGVV("%s: device 0x%x", __func__, device);
114    bassboost->device = device;
115}
116
117void offload_bassboost_set_enable_flag(struct bass_boost_params *bassboost,
118                                       bool enable)
119{
120    ALOGVV("%s: enable=%d", __func__, (int)enable);
121    bassboost->enable_flag = enable;
122}
123
124int offload_bassboost_get_enable_flag(struct bass_boost_params *bassboost)
125{
126    ALOGVV("%s: enable=%d", __func__, (int)bassboost->enable_flag);
127    return bassboost->enable_flag;
128}
129
130void offload_bassboost_set_strength(struct bass_boost_params *bassboost,
131                                    int strength)
132{
133    ALOGVV("%s: strength %d", __func__, strength);
134    bassboost->strength = strength;
135}
136
137void offload_bassboost_set_mode(struct bass_boost_params *bassboost,
138                                int mode)
139{
140    ALOGVV("%s: mode %d", __func__, mode);
141    bassboost->mode = mode;
142}
143
144int offload_bassboost_send_params(struct mixer_ctl *ctl,
145                                  struct bass_boost_params bassboost,
146                                  unsigned param_send_flags)
147{
148    int param_values[128] = {0};
149    int *p_param_values = param_values;
150
151    ALOGV("%s: flags 0x%x", __func__, param_send_flags);
152    *p_param_values++ = BASS_BOOST_MODULE;
153    *p_param_values++ = bassboost.device;
154    *p_param_values++ = 0; /* num of commands*/
155    if (param_send_flags & OFFLOAD_SEND_BASSBOOST_ENABLE_FLAG) {
156        *p_param_values++ = BASS_BOOST_ENABLE;
157        *p_param_values++ = CONFIG_SET;
158        *p_param_values++ = 0; /* start offset if param size if greater than 128  */
159        *p_param_values++ = BASS_BOOST_ENABLE_PARAM_LEN;
160        *p_param_values++ = bassboost.enable_flag;
161        param_values[2] += 1;
162    }
163    if (param_send_flags & OFFLOAD_SEND_BASSBOOST_STRENGTH) {
164        *p_param_values++ = BASS_BOOST_STRENGTH;
165        *p_param_values++ = CONFIG_SET;
166        *p_param_values++ = 0; /* start offset if param size if greater than 128  */
167        *p_param_values++ = BASS_BOOST_STRENGTH_PARAM_LEN;
168        *p_param_values++ = bassboost.strength;
169        param_values[2] += 1;
170    }
171    if (param_send_flags & OFFLOAD_SEND_BASSBOOST_MODE) {
172        *p_param_values++ = BASS_BOOST_MODE;
173        *p_param_values++ = CONFIG_SET;
174        *p_param_values++ = 0; /* start offset if param size if greater than 128  */
175        *p_param_values++ = BASS_BOOST_MODE_PARAM_LEN;
176        *p_param_values++ = bassboost.mode;
177        param_values[2] += 1;
178    }
179
180    if (param_values[2] && ctl)
181        mixer_ctl_set_array(ctl, param_values, ARRAY_SIZE(param_values));
182
183    return 0;
184}
185
186void offload_pbe_set_device(struct pbe_params *pbe,
187                            uint32_t device)
188{
189    ALOGV("%s: device=%d", __func__, device);
190    pbe->device = device;
191}
192
193void offload_pbe_set_enable_flag(struct pbe_params *pbe,
194                                 bool enable)
195{
196    ALOGV("%s: enable=%d", __func__, enable);
197    pbe->enable_flag = enable;
198}
199
200int offload_pbe_get_enable_flag(struct pbe_params *pbe)
201{
202    ALOGV("%s: enabled=%d", __func__, pbe->enable_flag);
203    return pbe->enable_flag;
204}
205
206static int pbe_send_params(eff_mode_t mode, void *ctl,
207                            struct pbe_params *pbe,
208                            unsigned param_send_flags)
209{
210    int param_values[128] = {0};
211    int i, *p_param_values = param_values, *cfg = NULL;
212
213    ALOGV("%s: enabled=%d", __func__, pbe->enable_flag);
214    *p_param_values++ = PBE_MODULE;
215    *p_param_values++ = pbe->device;
216    *p_param_values++ = 0; /* num of commands*/
217    if (param_send_flags & OFFLOAD_SEND_PBE_ENABLE_FLAG) {
218        *p_param_values++ = PBE_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++ = PBE_ENABLE_PARAM_LEN;
222        *p_param_values++ = pbe->enable_flag;
223        param_values[2] += 1;
224    }
225    if (param_send_flags & OFFLOAD_SEND_PBE_CONFIG) {
226        *p_param_values++ = PBE_CONFIG;
227        *p_param_values++ = CONFIG_SET;
228        *p_param_values++ = 0; /* start offset if param size if greater than 128  */
229        *p_param_values++ = pbe->cfg_len;
230        cfg = (int *)&pbe->config;
231        for (i = 0; i < (int)pbe->cfg_len ; i+= sizeof(*p_param_values))
232            *p_param_values++ = *cfg++;
233        param_values[2] += 1;
234    }
235
236    if ((mode == OFFLOAD) && param_values[2] && ctl) {
237        mixer_ctl_set_array((struct mixer_ctl *)ctl, param_values,
238                            ARRAY_SIZE(param_values));
239    }
240
241    return 0;
242}
243
244int offload_pbe_send_params(struct mixer_ctl *ctl,
245                                  struct pbe_params *pbe,
246                                  unsigned param_send_flags)
247{
248    return pbe_send_params(OFFLOAD, (void *)ctl, pbe,
249                                 param_send_flags);
250}
251
252void offload_virtualizer_set_device(struct virtualizer_params *virtualizer,
253                                    uint32_t device)
254{
255    ALOGVV("%s: device=0x%x", __func__, device);
256    virtualizer->device = device;
257}
258
259void offload_virtualizer_set_enable_flag(struct virtualizer_params *virtualizer,
260                                         bool enable)
261{
262    ALOGVV("%s: enable=%d", __func__, (int)enable);
263    virtualizer->enable_flag = enable;
264}
265
266int offload_virtualizer_get_enable_flag(struct virtualizer_params *virtualizer)
267{
268    ALOGVV("%s: enabled %d", __func__, (int)virtualizer->enable_flag);
269    return virtualizer->enable_flag;
270}
271
272void offload_virtualizer_set_strength(struct virtualizer_params *virtualizer,
273                                      int strength)
274{
275    ALOGVV("%s: strength %d", __func__, strength);
276    virtualizer->strength = strength;
277}
278
279void offload_virtualizer_set_out_type(struct virtualizer_params *virtualizer,
280                                      int out_type)
281{
282    ALOGVV("%s: out_type %d", __func__, out_type);
283    virtualizer->out_type = out_type;
284}
285
286void offload_virtualizer_set_gain_adjust(struct virtualizer_params *virtualizer,
287                                         int gain_adjust)
288{
289    ALOGVV("%s: gain %d", __func__, gain_adjust);
290    virtualizer->gain_adjust = gain_adjust;
291}
292
293int offload_virtualizer_send_params(struct mixer_ctl *ctl,
294                                    struct virtualizer_params virtualizer,
295                                    unsigned param_send_flags)
296{
297    int param_values[128] = {0};
298    int *p_param_values = param_values;
299
300    ALOGV("%s: flags 0x%x", __func__, param_send_flags);
301    *p_param_values++ = VIRTUALIZER_MODULE;
302    *p_param_values++ = virtualizer.device;
303    *p_param_values++ = 0; /* num of commands*/
304    if (param_send_flags & OFFLOAD_SEND_VIRTUALIZER_ENABLE_FLAG) {
305        *p_param_values++ = VIRTUALIZER_ENABLE;
306        *p_param_values++ = CONFIG_SET;
307        *p_param_values++ = 0; /* start offset if param size if greater than 128  */
308        *p_param_values++ = VIRTUALIZER_ENABLE_PARAM_LEN;
309        *p_param_values++ = virtualizer.enable_flag;
310        param_values[2] += 1;
311    }
312    if (param_send_flags & OFFLOAD_SEND_VIRTUALIZER_STRENGTH) {
313        *p_param_values++ = VIRTUALIZER_STRENGTH;
314        *p_param_values++ = CONFIG_SET;
315        *p_param_values++ = 0; /* start offset if param size if greater than 128  */
316        *p_param_values++ = VIRTUALIZER_STRENGTH_PARAM_LEN;
317        *p_param_values++ = virtualizer.strength;
318        param_values[2] += 1;
319    }
320    if (param_send_flags & OFFLOAD_SEND_VIRTUALIZER_OUT_TYPE) {
321        *p_param_values++ = VIRTUALIZER_OUT_TYPE;
322        *p_param_values++ = CONFIG_SET;
323        *p_param_values++ = 0; /* start offset if param size if greater than 128  */
324        *p_param_values++ = VIRTUALIZER_OUT_TYPE_PARAM_LEN;
325        *p_param_values++ = virtualizer.out_type;
326        param_values[2] += 1;
327    }
328    if (param_send_flags & OFFLOAD_SEND_VIRTUALIZER_GAIN_ADJUST) {
329        *p_param_values++ = VIRTUALIZER_GAIN_ADJUST;
330        *p_param_values++ = CONFIG_SET;
331        *p_param_values++ = 0; /* start offset if param size if greater than 128  */
332        *p_param_values++ = VIRTUALIZER_GAIN_ADJUST_PARAM_LEN;
333        *p_param_values++ = virtualizer.gain_adjust;
334        param_values[2] += 1;
335    }
336
337    if (param_values[2] && ctl)
338        mixer_ctl_set_array(ctl, param_values, ARRAY_SIZE(param_values));
339
340    return 0;
341}
342
343void offload_eq_set_device(struct eq_params *eq, uint32_t device)
344{
345    ALOGVV("%s: device 0x%x", __func__, device);
346    eq->device = device;
347}
348
349void offload_eq_set_enable_flag(struct eq_params *eq, bool enable)
350{
351    ALOGVV("%s: enable=%d", __func__, (int)enable);
352    eq->enable_flag = enable;
353}
354
355int offload_eq_get_enable_flag(struct eq_params *eq)
356{
357    ALOGVV("%s: enabled=%d", __func__, (int)eq->enable_flag);
358    return eq->enable_flag;
359}
360
361void offload_eq_set_preset(struct eq_params *eq, int preset)
362{
363    ALOGVV("%s: preset %d", __func__, preset);
364    eq->config.preset_id = preset;
365    eq->config.eq_pregain = Q27_UNITY;
366}
367
368void offload_eq_set_bands_level(struct eq_params *eq, int num_bands,
369                                const uint16_t *band_freq_list,
370                                int *band_gain_list)
371{
372    int i;
373    ALOGVV("%s", __func__);
374    eq->config.num_bands = num_bands;
375    for (i=0; i<num_bands; i++) {
376        eq->per_band_cfg[i].band_idx = i;
377        eq->per_band_cfg[i].filter_type = EQ_BAND_BOOST;
378        eq->per_band_cfg[i].freq_millihertz = band_freq_list[i] * 1000;
379        eq->per_band_cfg[i].gain_millibels = band_gain_list[i] * 100;
380        eq->per_band_cfg[i].quality_factor = Q8_UNITY;
381    }
382}
383
384int offload_eq_send_params(struct mixer_ctl *ctl, struct eq_params eq,
385                           unsigned param_send_flags)
386{
387    int param_values[128] = {0};
388    int *p_param_values = param_values;
389    uint32_t i;
390
391    ALOGV("%s: flags 0x%x", __func__, param_send_flags);
392    if ((eq.config.preset_id < -1) ||
393            ((param_send_flags & OFFLOAD_SEND_EQ_PRESET) && (eq.config.preset_id == -1))) {
394        ALOGV("No Valid preset to set");
395        return 0;
396    }
397    *p_param_values++ = EQ_MODULE;
398    *p_param_values++ = eq.device;
399    *p_param_values++ = 0; /* num of commands*/
400    if (param_send_flags & OFFLOAD_SEND_EQ_ENABLE_FLAG) {
401        *p_param_values++ = EQ_ENABLE;
402        *p_param_values++ = CONFIG_SET;
403        *p_param_values++ = 0; /* start offset if param size if greater than 128  */
404        *p_param_values++ = EQ_ENABLE_PARAM_LEN;
405        *p_param_values++ = eq.enable_flag;
406        param_values[2] += 1;
407    }
408    if (param_send_flags & OFFLOAD_SEND_EQ_PRESET) {
409        *p_param_values++ = EQ_CONFIG;
410        *p_param_values++ = CONFIG_SET;
411        *p_param_values++ = 0; /* start offset if param size if greater than 128  */
412        *p_param_values++ = EQ_CONFIG_PARAM_LEN;
413        *p_param_values++ = eq.config.eq_pregain;
414        *p_param_values++ =
415                     map_eq_opensl_preset_2_offload_preset[eq.config.preset_id];
416        *p_param_values++ = 0;
417        param_values[2] += 1;
418    }
419    if (param_send_flags & OFFLOAD_SEND_EQ_BANDS_LEVEL) {
420        *p_param_values++ = EQ_CONFIG;
421        *p_param_values++ = CONFIG_SET;
422        *p_param_values++ = 0; /* start offset if param size if greater than 128  */
423        *p_param_values++ = EQ_CONFIG_PARAM_LEN +
424                            eq.config.num_bands * EQ_CONFIG_PER_BAND_PARAM_LEN;
425        *p_param_values++ = eq.config.eq_pregain;
426        *p_param_values++ = CUSTOM_OPENSL_PRESET;
427        *p_param_values++ = eq.config.num_bands;
428        for (i=0; i<eq.config.num_bands; i++) {
429            *p_param_values++ = eq.per_band_cfg[i].band_idx;
430            *p_param_values++ = eq.per_band_cfg[i].filter_type;
431	    *p_param_values++ = eq.per_band_cfg[i].freq_millihertz;
432            *p_param_values++ = eq.per_band_cfg[i].gain_millibels;
433            *p_param_values++ = eq.per_band_cfg[i].quality_factor;
434        }
435        param_values[2] += 1;
436    }
437
438    if (param_values[2] && ctl)
439        mixer_ctl_set_array(ctl, param_values, ARRAY_SIZE(param_values));
440
441    return 0;
442}
443
444void offload_reverb_set_device(struct reverb_params *reverb, uint32_t device)
445{
446    ALOGVV("%s: device 0x%x", __func__, device);
447    reverb->device = device;
448}
449
450void offload_reverb_set_enable_flag(struct reverb_params *reverb, bool enable)
451{
452    ALOGVV("%s: enable=%d", __func__, (int)enable);
453    reverb->enable_flag = enable;
454}
455
456int offload_reverb_get_enable_flag(struct reverb_params *reverb)
457{
458    ALOGVV("%s: enabled=%d", __func__, reverb->enable_flag);
459    return reverb->enable_flag;
460}
461
462void offload_reverb_set_mode(struct reverb_params *reverb, int mode)
463{
464    ALOGVV("%s", __func__);
465    reverb->mode = mode;
466}
467
468void offload_reverb_set_preset(struct reverb_params *reverb, int preset)
469{
470    ALOGVV("%s: preset %d", __func__, preset);
471    if (preset && (preset <= NUM_OSL_REVERB_PRESETS_SUPPORTED))
472        reverb->preset = map_reverb_opensl_preset_2_offload_preset[preset-1][1];
473}
474
475void offload_reverb_set_wet_mix(struct reverb_params *reverb, int wet_mix)
476{
477    ALOGVV("%s: wet_mix %d", __func__, wet_mix);
478    reverb->wet_mix = wet_mix;
479}
480
481void offload_reverb_set_gain_adjust(struct reverb_params *reverb,
482                                    int gain_adjust)
483{
484    ALOGVV("%s: gain %d", __func__, gain_adjust);
485    reverb->gain_adjust = gain_adjust;
486}
487
488void offload_reverb_set_room_level(struct reverb_params *reverb, int room_level)
489{
490    ALOGVV("%s: level %d", __func__, room_level);
491    reverb->room_level = room_level;
492}
493
494void offload_reverb_set_room_hf_level(struct reverb_params *reverb,
495                                      int room_hf_level)
496{
497    ALOGVV("%s: level %d", __func__, room_hf_level);
498    reverb->room_hf_level = room_hf_level;
499}
500
501void offload_reverb_set_decay_time(struct reverb_params *reverb, int decay_time)
502{
503    ALOGVV("%s: decay time %d", __func__, decay_time);
504    reverb->decay_time = decay_time;
505}
506
507void offload_reverb_set_decay_hf_ratio(struct reverb_params *reverb,
508                                       int decay_hf_ratio)
509{
510    ALOGVV("%s: decay_hf_ratio %d", __func__, decay_hf_ratio);
511    reverb->decay_hf_ratio = decay_hf_ratio;
512}
513
514void offload_reverb_set_reflections_level(struct reverb_params *reverb,
515                                          int reflections_level)
516{
517    ALOGVV("%s: ref level %d", __func__, reflections_level);
518    reverb->reflections_level = reflections_level;
519}
520
521void offload_reverb_set_reflections_delay(struct reverb_params *reverb,
522                                          int reflections_delay)
523{
524    ALOGVV("%s: ref delay", __func__, reflections_delay);
525    reverb->reflections_delay = reflections_delay;
526}
527
528void offload_reverb_set_reverb_level(struct reverb_params *reverb,
529                                     int reverb_level)
530{
531    ALOGD("%s: reverb level %d", __func__, reverb_level);
532    reverb->level = reverb_level;
533}
534
535void offload_reverb_set_delay(struct reverb_params *reverb, int delay)
536{
537    ALOGVV("%s: delay %d", __func__, delay);
538    reverb->delay = delay;
539}
540
541void offload_reverb_set_diffusion(struct reverb_params *reverb, int diffusion)
542{
543    ALOGVV("%s: diffusion %d", __func__, diffusion);
544    reverb->diffusion = diffusion;
545}
546
547void offload_reverb_set_density(struct reverb_params *reverb, int density)
548{
549    ALOGVV("%s: density %d", __func__, density);
550    reverb->density = density;
551}
552
553int offload_reverb_send_params(struct mixer_ctl *ctl,
554                               struct reverb_params reverb,
555                               unsigned param_send_flags)
556{
557    int param_values[128] = {0};
558    int *p_param_values = param_values;
559
560    ALOGV("%s: flags 0x%x", __func__, param_send_flags);
561    *p_param_values++ = REVERB_MODULE;
562    *p_param_values++ = reverb.device;
563    *p_param_values++ = 0; /* num of commands*/
564
565    if (param_send_flags & OFFLOAD_SEND_REVERB_ENABLE_FLAG) {
566        *p_param_values++ = REVERB_ENABLE;
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_ENABLE_PARAM_LEN;
570        *p_param_values++ = reverb.enable_flag;
571        param_values[2] += 1;
572    }
573    if (param_send_flags & OFFLOAD_SEND_REVERB_MODE) {
574        *p_param_values++ = REVERB_MODE;
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_MODE_PARAM_LEN;
578        *p_param_values++ = reverb.mode;
579        param_values[2] += 1;
580    }
581    if (param_send_flags & OFFLOAD_SEND_REVERB_PRESET) {
582        *p_param_values++ = REVERB_PRESET;
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_PRESET_PARAM_LEN;
586        *p_param_values++ = reverb.preset;
587        param_values[2] += 1;
588    }
589    if (param_send_flags & OFFLOAD_SEND_REVERB_WET_MIX) {
590        *p_param_values++ = REVERB_WET_MIX;
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_WET_MIX_PARAM_LEN;
594        *p_param_values++ = reverb.wet_mix;
595        param_values[2] += 1;
596    }
597    if (param_send_flags & OFFLOAD_SEND_REVERB_GAIN_ADJUST) {
598        *p_param_values++ = REVERB_GAIN_ADJUST;
599        *p_param_values++ = CONFIG_SET;
600        *p_param_values++ = 0; /* start offset if param size if greater than 128  */
601        *p_param_values++ = REVERB_GAIN_ADJUST_PARAM_LEN;
602        *p_param_values++ = reverb.gain_adjust;
603        param_values[2] += 1;
604    }
605    if (param_send_flags & OFFLOAD_SEND_REVERB_ROOM_LEVEL) {
606        *p_param_values++ = REVERB_ROOM_LEVEL;
607        *p_param_values++ = CONFIG_SET;
608        *p_param_values++ = 0; /* start offset if param size if greater than 128  */
609        *p_param_values++ = REVERB_ROOM_LEVEL_PARAM_LEN;
610        *p_param_values++ = reverb.room_level;
611        param_values[2] += 1;
612    }
613    if (param_send_flags & OFFLOAD_SEND_REVERB_ROOM_HF_LEVEL) {
614        *p_param_values++ = REVERB_ROOM_HF_LEVEL;
615        *p_param_values++ = CONFIG_SET;
616        *p_param_values++ = 0; /* start offset if param size if greater than 128  */
617        *p_param_values++ = REVERB_ROOM_HF_LEVEL_PARAM_LEN;
618        *p_param_values++ = reverb.room_hf_level;
619        param_values[2] += 1;
620    }
621    if (param_send_flags & OFFLOAD_SEND_REVERB_DECAY_TIME) {
622        *p_param_values++ = REVERB_DECAY_TIME;
623        *p_param_values++ = CONFIG_SET;
624        *p_param_values++ = 0; /* start offset if param size if greater than 128  */
625        *p_param_values++ = REVERB_DECAY_TIME_PARAM_LEN;
626        *p_param_values++ = reverb.decay_time;
627        param_values[2] += 1;
628    }
629    if (param_send_flags & OFFLOAD_SEND_REVERB_DECAY_HF_RATIO) {
630        *p_param_values++ = REVERB_DECAY_HF_RATIO;
631        *p_param_values++ = CONFIG_SET;
632        *p_param_values++ = 0; /* start offset if param size if greater than 128  */
633        *p_param_values++ = REVERB_DECAY_HF_RATIO_PARAM_LEN;
634        *p_param_values++ = reverb.decay_hf_ratio;
635        param_values[2] += 1;
636    }
637    if (param_send_flags & OFFLOAD_SEND_REVERB_REFLECTIONS_LEVEL) {
638        *p_param_values++ = REVERB_REFLECTIONS_LEVEL;
639        *p_param_values++ = CONFIG_SET;
640        *p_param_values++ = 0; /* start offset if param size if greater than 128  */
641        *p_param_values++ = REVERB_REFLECTIONS_LEVEL_PARAM_LEN;
642        *p_param_values++ = reverb.reflections_level;
643        param_values[2] += 1;
644    }
645    if (param_send_flags & OFFLOAD_SEND_REVERB_REFLECTIONS_DELAY) {
646        *p_param_values++ = REVERB_REFLECTIONS_DELAY;
647        *p_param_values++ = CONFIG_SET;
648        *p_param_values++ = 0; /* start offset if param size if greater than 128  */
649        *p_param_values++ = REVERB_REFLECTIONS_DELAY_PARAM_LEN;
650        *p_param_values++ = reverb.reflections_delay;
651        param_values[2] += 1;
652    }
653    if (param_send_flags & OFFLOAD_SEND_REVERB_LEVEL) {
654        *p_param_values++ = REVERB_LEVEL;
655        *p_param_values++ = CONFIG_SET;
656        *p_param_values++ = 0; /* start offset if param size if greater than 128  */
657        *p_param_values++ = REVERB_LEVEL_PARAM_LEN;
658        *p_param_values++ = reverb.level;
659        param_values[2] += 1;
660    }
661    if (param_send_flags & OFFLOAD_SEND_REVERB_DELAY) {
662        *p_param_values++ = REVERB_DELAY;
663        *p_param_values++ = CONFIG_SET;
664        *p_param_values++ = 0; /* start offset if param size if greater than 128  */
665        *p_param_values++ = REVERB_DELAY_PARAM_LEN;
666        *p_param_values++ = reverb.delay;
667        param_values[2] += 1;
668    }
669    if (param_send_flags & OFFLOAD_SEND_REVERB_DIFFUSION) {
670        *p_param_values++ = REVERB_DIFFUSION;
671        *p_param_values++ = CONFIG_SET;
672        *p_param_values++ = 0; /* start offset if param size if greater than 128  */
673        *p_param_values++ = REVERB_DIFFUSION_PARAM_LEN;
674        *p_param_values++ = reverb.diffusion;
675        param_values[2] += 1;
676    }
677    if (param_send_flags & OFFLOAD_SEND_REVERB_DENSITY) {
678        *p_param_values++ = REVERB_DENSITY;
679        *p_param_values++ = CONFIG_SET;
680        *p_param_values++ = 0; /* start offset if param size if greater than 128  */
681        *p_param_values++ = REVERB_DENSITY_PARAM_LEN;
682        *p_param_values++ = reverb.density;
683        param_values[2] += 1;
684    }
685
686    if (param_values[2] && ctl)
687        mixer_ctl_set_array(ctl, param_values, ARRAY_SIZE(param_values));
688
689    return 0;
690}
691