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