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_reverb"
18//#define LOG_NDEBUG 0
19
20#include <cutils/list.h>
21#include <cutils/log.h>
22#include <tinyalsa/asoundlib.h>
23#include <sound/audio_effects.h>
24#include <audio_effects/effect_environmentalreverb.h>
25#include <audio_effects/effect_presetreverb.h>
26
27#include "effect_api.h"
28#include "reverb.h"
29
30/* Offload auxiliary environmental reverb UUID: 79a18026-18fd-4185-8233-0002a5d5c51b */
31const effect_descriptor_t aux_env_reverb_descriptor = {
32        { 0xc2e5d5f0, 0x94bd, 0x4763, 0x9cac, { 0x4e, 0x23, 0x4d, 0x06, 0x83, 0x9e } },
33        { 0x79a18026, 0x18fd, 0x4185, 0x8233, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } },
34        EFFECT_CONTROL_API_VERSION,
35        (EFFECT_FLAG_TYPE_AUXILIARY | EFFECT_FLAG_HW_ACC_TUNNEL | EFFECT_FLAG_VOLUME_CTRL),
36        0, /* TODO */
37        1,
38        "MSM offload Auxiliary Environmental Reverb",
39        "The Android Open Source Project",
40};
41
42/* Offload insert environmental reverb UUID: eb64ea04-973b-43d2-8f5e-0002a5d5c51b */
43const effect_descriptor_t ins_env_reverb_descriptor = {
44        {0xc2e5d5f0, 0x94bd, 0x4763, 0x9cac, {0x4e, 0x23, 0x4d, 0x06, 0x83, 0x9e}},
45        {0xeb64ea04, 0x973b, 0x43d2, 0x8f5e, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}},
46        EFFECT_CONTROL_API_VERSION,
47        (EFFECT_FLAG_TYPE_INSERT | EFFECT_FLAG_INSERT_FIRST | EFFECT_FLAG_HW_ACC_TUNNEL |
48                EFFECT_FLAG_VOLUME_CTRL),
49        0, /* TODO */
50        1,
51        "MSM offload Insert Environmental Reverb",
52        "The Android Open Source Project",
53};
54
55// Offload auxiliary preset reverb UUID: 6987be09-b142-4b41-9056-0002a5d5c51b */
56const effect_descriptor_t aux_preset_reverb_descriptor = {
57        {0x47382d60, 0xddd8, 0x11db, 0xbf3a, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}},
58        {0x6987be09, 0xb142, 0x4b41, 0x9056, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}},
59        EFFECT_CONTROL_API_VERSION,
60        (EFFECT_FLAG_TYPE_AUXILIARY | EFFECT_FLAG_HW_ACC_TUNNEL | EFFECT_FLAG_VOLUME_CTRL),
61        0, /* TODO */
62        1,
63        "MSM offload Auxiliary Preset Reverb",
64        "The Android Open Source Project",
65};
66
67// Offload insert preset reverb UUID: aa2bebf6-47cf-4613-9bca-0002a5d5c51b */
68const effect_descriptor_t ins_preset_reverb_descriptor = {
69        {0x47382d60, 0xddd8, 0x11db, 0xbf3a, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}},
70        {0xaa2bebf6, 0x47cf, 0x4613, 0x9bca, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}},
71        EFFECT_CONTROL_API_VERSION,
72        (EFFECT_FLAG_TYPE_INSERT | EFFECT_FLAG_INSERT_FIRST | EFFECT_FLAG_HW_ACC_TUNNEL |
73                EFFECT_FLAG_VOLUME_CTRL),
74        0, /* TODO */
75        1,
76        "MSM offload Insert Preset Reverb",
77        "The Android Open Source Project",
78};
79
80static const reverb_settings_t reverb_presets[] = {
81        // REVERB_PRESET_NONE: values are unused
82        {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
83        // REVERB_PRESET_SMALLROOM
84        {-400, -600, 1100, 830, -400, 5, 500, 10, 1000, 1000},
85        // REVERB_PRESET_MEDIUMROOM
86        {-400, -600, 1300, 830, -1000, 20, -200, 20, 1000, 1000},
87        // REVERB_PRESET_LARGEROOM
88        {-400, -600, 1500, 830, -1600, 5, -1000, 40, 1000, 1000},
89        // REVERB_PRESET_MEDIUMHALL
90        {-400, -600, 1800, 700, -1300, 15, -800, 30, 1000, 1000},
91        // REVERB_PRESET_LARGEHALL
92        {-400, -600, 1800, 700, -2000, 30, -1400, 60, 1000, 1000},
93        // REVERB_PRESET_PLATE
94        {-400, -200, 1300, 900, 0, 2, 0, 10, 1000, 750},
95};
96
97
98void reverb_auxiliary_init(reverb_context_t *context)
99{
100    context->auxiliary = true;
101    context->preset = false;
102}
103
104void reverb_insert_init(reverb_context_t *context)
105{
106    context->auxiliary = false;
107    context->preset = true;
108    context->cur_preset = REVERB_PRESET_LAST + 1;
109    context->next_preset = REVERB_DEFAULT_PRESET;
110}
111
112void reverb_preset_init(reverb_context_t *context)
113{
114    context->auxiliary = false;
115    context->preset = true;
116    context->cur_preset = REVERB_PRESET_LAST + 1;
117    context->next_preset = REVERB_DEFAULT_PRESET;
118}
119
120/*
121 * Reverb operations
122 */
123int16_t reverb_get_room_level(reverb_context_t *context)
124{
125    ALOGV("%s: room level: %d", __func__, context->reverb_settings.roomLevel);
126    return context->reverb_settings.roomLevel;
127}
128
129void reverb_set_room_level(reverb_context_t *context, int16_t room_level)
130{
131    ALOGV("%s: room level: %d", __func__, room_level);
132    context->reverb_settings.roomLevel = room_level;
133    offload_reverb_set_room_level(&(context->offload_reverb), room_level);
134    if (context->ctl)
135        offload_reverb_send_params(context->ctl, &context->offload_reverb,
136                                   OFFLOAD_SEND_REVERB_ENABLE_FLAG |
137                                   OFFLOAD_SEND_REVERB_ROOM_LEVEL);
138}
139
140int16_t reverb_get_room_hf_level(reverb_context_t *context)
141{
142    ALOGV("%s: room hf level: %d", __func__,
143          context->reverb_settings.roomHFLevel);
144    return context->reverb_settings.roomHFLevel;
145}
146
147void reverb_set_room_hf_level(reverb_context_t *context, int16_t room_hf_level)
148{
149    ALOGV("%s: room hf level: %d", __func__, room_hf_level);
150    context->reverb_settings.roomHFLevel = room_hf_level;
151    offload_reverb_set_room_hf_level(&(context->offload_reverb), room_hf_level);
152    if (context->ctl)
153        offload_reverb_send_params(context->ctl, &context->offload_reverb,
154                                   OFFLOAD_SEND_REVERB_ENABLE_FLAG |
155                                   OFFLOAD_SEND_REVERB_ROOM_HF_LEVEL);
156}
157
158uint32_t reverb_get_decay_time(reverb_context_t *context)
159{
160    ALOGV("%s: decay time: %d", __func__, context->reverb_settings.decayTime);
161    return context->reverb_settings.decayTime;
162}
163
164void reverb_set_decay_time(reverb_context_t *context, uint32_t decay_time)
165{
166    ALOGV("%s: decay_time: %d", __func__, decay_time);
167    context->reverb_settings.decayTime = decay_time;
168    offload_reverb_set_decay_time(&(context->offload_reverb), decay_time);
169    if (context->ctl)
170        offload_reverb_send_params(context->ctl, &context->offload_reverb,
171                                   OFFLOAD_SEND_REVERB_ENABLE_FLAG |
172                                   OFFLOAD_SEND_REVERB_DECAY_TIME);
173}
174
175int16_t reverb_get_decay_hf_ratio(reverb_context_t *context)
176{
177    ALOGV("%s: decay hf ratio: %d", __func__,
178          context->reverb_settings.decayHFRatio);
179    return context->reverb_settings.decayHFRatio;
180}
181
182void reverb_set_decay_hf_ratio(reverb_context_t *context, int16_t decay_hf_ratio)
183{
184    ALOGV("%s: decay_hf_ratio: %d", __func__, decay_hf_ratio);
185    context->reverb_settings.decayHFRatio = decay_hf_ratio;
186    offload_reverb_set_decay_hf_ratio(&(context->offload_reverb), decay_hf_ratio);
187    if (context->ctl)
188        offload_reverb_send_params(context->ctl, &context->offload_reverb,
189                                   OFFLOAD_SEND_REVERB_ENABLE_FLAG |
190                                   OFFLOAD_SEND_REVERB_DECAY_HF_RATIO);
191}
192
193int16_t reverb_get_reverb_level(reverb_context_t *context)
194{
195    ALOGV("%s: reverb level: %d", __func__, context->reverb_settings.reverbLevel);
196    return context->reverb_settings.reverbLevel;
197}
198
199void reverb_set_reverb_level(reverb_context_t *context, int16_t reverb_level)
200{
201    ALOGV("%s: reverb level: %d", __func__, reverb_level);
202    context->reverb_settings.reverbLevel = reverb_level;
203    offload_reverb_set_reverb_level(&(context->offload_reverb), reverb_level);
204    if (context->ctl)
205        offload_reverb_send_params(context->ctl, &context->offload_reverb,
206                                   OFFLOAD_SEND_REVERB_ENABLE_FLAG |
207                                   OFFLOAD_SEND_REVERB_LEVEL);
208}
209
210int16_t reverb_get_diffusion(reverb_context_t *context)
211{
212    ALOGV("%s: diffusion: %d", __func__, context->reverb_settings.diffusion);
213    return context->reverb_settings.diffusion;
214}
215
216void reverb_set_diffusion(reverb_context_t *context, int16_t diffusion)
217{
218    ALOGV("%s: diffusion: %d", __func__, diffusion);
219    context->reverb_settings.diffusion = diffusion;
220    offload_reverb_set_diffusion(&(context->offload_reverb), diffusion);
221    if (context->ctl)
222        offload_reverb_send_params(context->ctl, &context->offload_reverb,
223                                   OFFLOAD_SEND_REVERB_ENABLE_FLAG |
224                                   OFFLOAD_SEND_REVERB_DIFFUSION);
225}
226
227int16_t reverb_get_density(reverb_context_t *context)
228{
229    ALOGV("%s: density: %d", __func__, context->reverb_settings.density);
230    return context->reverb_settings.density;
231}
232
233void reverb_set_density(reverb_context_t *context, int16_t density)
234{
235    ALOGV("%s: density: %d", __func__, density);
236    context->reverb_settings.density = density;
237    offload_reverb_set_density(&(context->offload_reverb), density);
238    if (context->ctl)
239        offload_reverb_send_params(context->ctl, &context->offload_reverb,
240                                   OFFLOAD_SEND_REVERB_ENABLE_FLAG |
241                                   OFFLOAD_SEND_REVERB_DENSITY);
242}
243
244void reverb_set_preset(reverb_context_t *context, int16_t preset)
245{
246    bool enable;
247    ALOGV("%s: preset: %d", __func__, preset);
248    context->next_preset = preset;
249    offload_reverb_set_preset(&(context->offload_reverb), preset);
250
251    enable = (preset == REVERB_PRESET_NONE) ? false: true;
252    offload_reverb_set_enable_flag(&(context->offload_reverb), enable);
253
254    if (context->ctl)
255        offload_reverb_send_params(context->ctl, &context->offload_reverb,
256                                   OFFLOAD_SEND_REVERB_ENABLE_FLAG |
257                                   OFFLOAD_SEND_REVERB_PRESET);
258}
259
260void reverb_set_all_properties(reverb_context_t *context,
261                               reverb_settings_t *reverb_settings)
262{
263    ALOGV("%s", __func__);
264    context->reverb_settings.roomLevel = reverb_settings->roomLevel;
265    context->reverb_settings.roomHFLevel = reverb_settings->roomHFLevel;
266    context->reverb_settings.decayTime = reverb_settings->decayTime;
267    context->reverb_settings.decayHFRatio = reverb_settings->decayHFRatio;
268    context->reverb_settings.reverbLevel = reverb_settings->reverbLevel;
269    context->reverb_settings.diffusion = reverb_settings->diffusion;
270    context->reverb_settings.density = reverb_settings->density;
271    if (context->ctl)
272        offload_reverb_send_params(context->ctl, &context->offload_reverb,
273                                   OFFLOAD_SEND_REVERB_ENABLE_FLAG |
274                                   OFFLOAD_SEND_REVERB_ROOM_LEVEL |
275                                   OFFLOAD_SEND_REVERB_ROOM_HF_LEVEL |
276                                   OFFLOAD_SEND_REVERB_DECAY_TIME |
277                                   OFFLOAD_SEND_REVERB_DECAY_HF_RATIO |
278                                   OFFLOAD_SEND_REVERB_LEVEL |
279                                   OFFLOAD_SEND_REVERB_DIFFUSION |
280                                   OFFLOAD_SEND_REVERB_DENSITY);
281}
282
283void reverb_load_preset(reverb_context_t *context)
284{
285    context->cur_preset = context->next_preset;
286
287    if (context->cur_preset != REVERB_PRESET_NONE) {
288        const reverb_settings_t *preset = &reverb_presets[context->cur_preset];
289        reverb_set_room_level(context, preset->roomLevel);
290        reverb_set_room_hf_level(context, preset->roomHFLevel);
291        reverb_set_decay_time(context, preset->decayTime);
292        reverb_set_decay_hf_ratio(context, preset->decayHFRatio);
293        reverb_set_reverb_level(context, preset->reverbLevel);
294        reverb_set_diffusion(context, preset->diffusion);
295        reverb_set_density(context, preset->density);
296    }
297}
298
299int reverb_get_parameter(effect_context_t *context, effect_param_t *p,
300                         uint32_t *size)
301{
302    reverb_context_t *reverb_ctxt = (reverb_context_t *)context;
303    int voffset = ((p->psize - 1) / sizeof(int32_t) + 1) * sizeof(int32_t);
304    int32_t *param_tmp = (int32_t *)p->data;
305    int32_t param = *param_tmp++;
306    void *value = p->data + voffset;
307    reverb_settings_t *reverb_settings;
308    int i;
309
310    ALOGV("%s", __func__);
311
312    p->status = 0;
313
314    if (reverb_ctxt->preset) {
315        if (param != REVERB_PARAM_PRESET || p->vsize < sizeof(uint16_t))
316            return -EINVAL;
317        *(uint16_t *)value = reverb_ctxt->next_preset;
318        ALOGV("get REVERB_PARAM_PRESET, preset %d", reverb_ctxt->next_preset);
319        return 0;
320    }
321    switch (param) {
322    case REVERB_PARAM_ROOM_LEVEL:
323        if (p->vsize < sizeof(uint16_t))
324           p->status = -EINVAL;
325        p->vsize = sizeof(uint16_t);
326        break;
327    case REVERB_PARAM_ROOM_HF_LEVEL:
328        if (p->vsize < sizeof(uint16_t))
329           p->status = -EINVAL;
330        p->vsize = sizeof(uint16_t);
331        break;
332    case REVERB_PARAM_DECAY_TIME:
333        if (p->vsize < sizeof(uint32_t))
334           p->status = -EINVAL;
335        p->vsize = sizeof(uint32_t);
336        break;
337    case REVERB_PARAM_DECAY_HF_RATIO:
338        if (p->vsize < sizeof(uint16_t))
339           p->status = -EINVAL;
340        p->vsize = sizeof(uint16_t);
341        break;
342    case REVERB_PARAM_REFLECTIONS_LEVEL:
343        if (p->vsize < sizeof(uint16_t))
344           p->status = -EINVAL;
345        p->vsize = sizeof(uint16_t);
346        break;
347    case REVERB_PARAM_REFLECTIONS_DELAY:
348        if (p->vsize < sizeof(uint32_t))
349           p->status = -EINVAL;
350        p->vsize = sizeof(uint32_t);
351        break;
352    case REVERB_PARAM_REVERB_LEVEL:
353        if (p->vsize < sizeof(uint16_t))
354           p->status = -EINVAL;
355        p->vsize = sizeof(uint16_t);
356        break;
357    case REVERB_PARAM_REVERB_DELAY:
358        if (p->vsize < sizeof(uint32_t))
359           p->status = -EINVAL;
360        p->vsize = sizeof(uint32_t);
361        break;
362    case REVERB_PARAM_DIFFUSION:
363        if (p->vsize < sizeof(uint16_t))
364           p->status = -EINVAL;
365        p->vsize = sizeof(uint16_t);
366        break;
367    case REVERB_PARAM_DENSITY:
368        if (p->vsize < sizeof(uint16_t))
369           p->status = -EINVAL;
370        p->vsize = sizeof(uint16_t);
371        break;
372    case REVERB_PARAM_PROPERTIES:
373        if (p->vsize < sizeof(reverb_settings_t))
374           p->status = -EINVAL;
375        p->vsize = sizeof(reverb_settings_t);
376        break;
377    default:
378        p->status = -EINVAL;
379    }
380
381    *size = sizeof(effect_param_t) + voffset + p->vsize;
382
383    if (p->status != 0)
384        return 0;
385
386    switch (param) {
387    case REVERB_PARAM_PROPERTIES:
388	ALOGV("%s: REVERB_PARAM_PROPERTIES", __func__);
389        reverb_settings = (reverb_settings_t *)value;
390        reverb_settings->roomLevel = reverb_get_room_level(reverb_ctxt);
391        reverb_settings->roomHFLevel = reverb_get_room_hf_level(reverb_ctxt);
392        reverb_settings->decayTime = reverb_get_decay_time(reverb_ctxt);
393        reverb_settings->decayHFRatio = reverb_get_decay_hf_ratio(reverb_ctxt);
394        reverb_settings->reflectionsLevel = 0;
395        reverb_settings->reflectionsDelay = 0;
396        reverb_settings->reverbDelay = 0;
397        reverb_settings->reverbLevel = reverb_get_reverb_level(reverb_ctxt);
398        reverb_settings->diffusion = reverb_get_diffusion(reverb_ctxt);
399        reverb_settings->density = reverb_get_density(reverb_ctxt);
400        break;
401    case REVERB_PARAM_ROOM_LEVEL:
402	ALOGV("%s: REVERB_PARAM_ROOM_LEVEL", __func__);
403        *(int16_t *)value = reverb_get_room_level(reverb_ctxt);
404        break;
405    case REVERB_PARAM_ROOM_HF_LEVEL:
406	ALOGV("%s: REVERB_PARAM_ROOM_HF_LEVEL", __func__);
407        *(int16_t *)value = reverb_get_room_hf_level(reverb_ctxt);
408        break;
409    case REVERB_PARAM_DECAY_TIME:
410	ALOGV("%s: REVERB_PARAM_DECAY_TIME", __func__);
411        *(uint32_t *)value = reverb_get_decay_time(reverb_ctxt);
412        break;
413    case REVERB_PARAM_DECAY_HF_RATIO:
414	ALOGV("%s: REVERB_PARAM_DECAY_HF_RATIO", __func__);
415        *(int16_t *)value = reverb_get_decay_hf_ratio(reverb_ctxt);
416        break;
417    case REVERB_PARAM_REVERB_LEVEL:
418	ALOGV("%s: REVERB_PARAM_REVERB_LEVEL", __func__);
419        *(int16_t *)value = reverb_get_reverb_level(reverb_ctxt);
420        break;
421    case REVERB_PARAM_DIFFUSION:
422	ALOGV("%s: REVERB_PARAM_DIFFUSION", __func__);
423        *(int16_t *)value = reverb_get_diffusion(reverb_ctxt);
424        break;
425    case REVERB_PARAM_DENSITY:
426	ALOGV("%s: REVERB_PARAM_DENSITY", __func__);
427        *(int16_t *)value = reverb_get_density(reverb_ctxt);
428        break;
429    case REVERB_PARAM_REFLECTIONS_LEVEL:
430	ALOGV("%s: REVERB_PARAM_REFLECTIONS_LEVEL", __func__);
431        *(uint16_t *)value = 0;
432        break;
433    case REVERB_PARAM_REFLECTIONS_DELAY:
434	ALOGV("%s: REVERB_PARAM_REFLECTIONS_DELAY", __func__);
435        *(uint32_t *)value = 0;
436        break;
437    case REVERB_PARAM_REVERB_DELAY:
438	ALOGV("%s: REVERB_PARAM_REVERB_DELAY", __func__);
439        *(uint32_t *)value = 0;
440        break;
441    default:
442        p->status = -EINVAL;
443        break;
444    }
445
446    return 0;
447}
448
449int reverb_set_parameter(effect_context_t *context, effect_param_t *p,
450                         uint32_t size __unused)
451{
452    reverb_context_t *reverb_ctxt = (reverb_context_t *)context;
453    int voffset = ((p->psize - 1) / sizeof(int32_t) + 1) * sizeof(int32_t);
454    void *value = p->data + voffset;
455    int32_t *param_tmp = (int32_t *)p->data;
456    int32_t param = *param_tmp++;
457    reverb_settings_t *reverb_settings;
458    int16_t level;
459    int16_t ratio;
460    uint32_t time;
461
462    ALOGV("%s", __func__);
463
464    p->status = 0;
465
466    if (reverb_ctxt->preset) {
467        if (param != REVERB_PARAM_PRESET)
468            return -EINVAL;
469        uint16_t preset = *(uint16_t *)value;
470        ALOGV("set REVERB_PARAM_PRESET, preset %d", preset);
471        if (preset > REVERB_PRESET_LAST) {
472            return -EINVAL;
473        }
474        reverb_set_preset(reverb_ctxt, preset);
475        return 0;
476    }
477    switch (param) {
478    case REVERB_PARAM_PROPERTIES:
479	ALOGV("%s: REVERB_PARAM_PROPERTIES", __func__);
480        reverb_settings = (reverb_settings_t *)value;
481        break;
482    case REVERB_PARAM_ROOM_LEVEL:
483	ALOGV("%s: REVERB_PARAM_ROOM_LEVEL", __func__);
484        level = *(int16_t *)value;
485        reverb_set_room_level(reverb_ctxt, level);
486        break;
487    case REVERB_PARAM_ROOM_HF_LEVEL:
488	ALOGV("%s: REVERB_PARAM_ROOM_HF_LEVEL", __func__);
489        level = *(int16_t *)value;
490        reverb_set_room_hf_level(reverb_ctxt, level);
491        break;
492    case REVERB_PARAM_DECAY_TIME:
493	ALOGV("%s: REVERB_PARAM_DECAY_TIME", __func__);
494        time = *(uint32_t *)value;
495        reverb_set_decay_time(reverb_ctxt, time);
496        break;
497    case REVERB_PARAM_DECAY_HF_RATIO:
498	ALOGV("%s: REVERB_PARAM_DECAY_HF_RATIO", __func__);
499        ratio = *(int16_t *)value;
500        reverb_set_decay_hf_ratio(reverb_ctxt, ratio);
501        break;
502    case REVERB_PARAM_REVERB_LEVEL:
503	ALOGV("%s: REVERB_PARAM_REVERB_LEVEL", __func__);
504        level = *(int16_t *)value;
505        reverb_set_reverb_level(reverb_ctxt, level);
506        break;
507    case REVERB_PARAM_DIFFUSION:
508	ALOGV("%s: REVERB_PARAM_DIFFUSION", __func__);
509        ratio = *(int16_t *)value;
510        reverb_set_diffusion(reverb_ctxt, ratio);
511        break;
512    case REVERB_PARAM_DENSITY:
513	ALOGV("%s: REVERB_PARAM_DENSITY", __func__);
514        ratio = *(int16_t *)value;
515        reverb_set_density(reverb_ctxt, ratio);
516        break;
517    case REVERB_PARAM_REFLECTIONS_LEVEL:
518    case REVERB_PARAM_REFLECTIONS_DELAY:
519    case REVERB_PARAM_REVERB_DELAY:
520        break;
521    default:
522        p->status = -EINVAL;
523        break;
524    }
525
526    return 0;
527}
528
529int reverb_set_device(effect_context_t *context, uint32_t device)
530{
531    reverb_context_t *reverb_ctxt = (reverb_context_t *)context;
532
533    ALOGV("%s: device: %d", __func__, device);
534    reverb_ctxt->device = device;
535    offload_reverb_set_device(&(reverb_ctxt->offload_reverb), device);
536    return 0;
537}
538
539int reverb_reset(effect_context_t *context)
540{
541    reverb_context_t *reverb_ctxt = (reverb_context_t *)context;
542
543    return 0;
544}
545
546int reverb_init(effect_context_t *context)
547{
548    reverb_context_t *reverb_ctxt = (reverb_context_t *)context;
549
550    context->config.inputCfg.accessMode = EFFECT_BUFFER_ACCESS_READ;
551    /*
552       FIXME: channel mode is mono for auxiliary. is it needed for offload ?
553              If so, this set config needs to be updated accordingly
554    */
555    context->config.inputCfg.channels = AUDIO_CHANNEL_OUT_STEREO;
556    context->config.inputCfg.format = AUDIO_FORMAT_PCM_16_BIT;
557    context->config.inputCfg.samplingRate = 44100;
558    context->config.inputCfg.bufferProvider.getBuffer = NULL;
559    context->config.inputCfg.bufferProvider.releaseBuffer = NULL;
560    context->config.inputCfg.bufferProvider.cookie = NULL;
561    context->config.inputCfg.mask = EFFECT_CONFIG_ALL;
562    context->config.outputCfg.accessMode = EFFECT_BUFFER_ACCESS_ACCUMULATE;
563    context->config.outputCfg.channels = AUDIO_CHANNEL_OUT_STEREO;
564    context->config.outputCfg.format = AUDIO_FORMAT_PCM_16_BIT;
565    context->config.outputCfg.samplingRate = 44100;
566    context->config.outputCfg.bufferProvider.getBuffer = NULL;
567    context->config.outputCfg.bufferProvider.releaseBuffer = NULL;
568    context->config.outputCfg.bufferProvider.cookie = NULL;
569    context->config.outputCfg.mask = EFFECT_CONFIG_ALL;
570
571    set_config(context, &context->config);
572
573    memset(&(reverb_ctxt->reverb_settings), 0, sizeof(reverb_settings_t));
574    memset(&(reverb_ctxt->offload_reverb), 0, sizeof(struct reverb_params));
575
576    if (reverb_ctxt->preset &&
577        reverb_ctxt->next_preset != reverb_ctxt->cur_preset)
578        reverb_load_preset(reverb_ctxt);
579
580    return 0;
581}
582
583int reverb_enable(effect_context_t *context)
584{
585    reverb_context_t *reverb_ctxt = (reverb_context_t *)context;
586
587    ALOGV("%s", __func__);
588
589    if (!offload_reverb_get_enable_flag(&(reverb_ctxt->offload_reverb)))
590        offload_reverb_set_enable_flag(&(reverb_ctxt->offload_reverb), true);
591    return 0;
592}
593
594int reverb_disable(effect_context_t *context)
595{
596    reverb_context_t *reverb_ctxt = (reverb_context_t *)context;
597
598    ALOGV("%s", __func__);
599    if (offload_reverb_get_enable_flag(&(reverb_ctxt->offload_reverb))) {
600        offload_reverb_set_enable_flag(&(reverb_ctxt->offload_reverb), false);
601        if (reverb_ctxt->ctl)
602            offload_reverb_send_params(reverb_ctxt->ctl,
603                                       &reverb_ctxt->offload_reverb,
604                                       OFFLOAD_SEND_REVERB_ENABLE_FLAG);
605    }
606    return 0;
607}
608
609int reverb_start(effect_context_t *context, output_context_t *output)
610{
611    reverb_context_t *reverb_ctxt = (reverb_context_t *)context;
612
613    ALOGV("%s", __func__);
614    reverb_ctxt->ctl = output->ctl;
615    if (offload_reverb_get_enable_flag(&(reverb_ctxt->offload_reverb))) {
616        if (reverb_ctxt->ctl && reverb_ctxt->preset) {
617            offload_reverb_send_params(reverb_ctxt->ctl, &reverb_ctxt->offload_reverb,
618                                       OFFLOAD_SEND_REVERB_ENABLE_FLAG |
619                                       OFFLOAD_SEND_REVERB_PRESET);
620        }
621    }
622
623    return 0;
624}
625
626int reverb_stop(effect_context_t *context, output_context_t *output __unused)
627{
628    reverb_context_t *reverb_ctxt = (reverb_context_t *)context;
629
630    ALOGV("%s", __func__);
631    reverb_ctxt->ctl = NULL;
632    return 0;
633}
634
635