Home | History | Annotate | Download | only in post_proc
      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_equalizer"
     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_equalizer.h>
     25 
     26 #include "effect_api.h"
     27 #include "equalizer.h"
     28 
     29 /* Offload equalizer UUID: a0dac280-401c-11e3-9379-0002a5d5c51b */
     30 const effect_descriptor_t equalizer_descriptor = {
     31         {0x0bed4300, 0xddd6, 0x11db, 0x8f34, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}}, // type
     32         {0xa0dac280, 0x401c, 0x11e3, 0x9379, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}}, // uuid
     33         EFFECT_CONTROL_API_VERSION,
     34         (EFFECT_FLAG_TYPE_INSERT | EFFECT_FLAG_HW_ACC_TUNNEL | EFFECT_FLAG_VOLUME_CTRL),
     35         0, /* TODO */
     36         1,
     37         "MSM offload equalizer",
     38         "The Android Open Source Project",
     39 };
     40 
     41 static const char *equalizer_preset_names[] = {
     42                                         "Normal",
     43                                         "Classical",
     44                                         "Dance",
     45                                         "Flat",
     46                                         "Folk",
     47                                         "Heavy Metal",
     48                                         "Hip Hop",
     49                                         "Jazz",
     50                                         "Pop",
     51                                         "Rock"
     52 					};
     53 
     54 static const uint32_t equalizer_band_freq_range[NUM_EQ_BANDS][2] = {
     55                                        {30000, 120000},
     56                                        {120001, 460000},
     57                                        {460001, 1800000},
     58                                        {1800001, 7000000},
     59                                        {7000001, 20000000}};
     60 
     61 static const int16_t equalizer_band_presets_level[] = {
     62                                         3, 0, 0, 0, 3,      /* Normal Preset */
     63                                         5, 3, -2, 4, 4,     /* Classical Preset */
     64                                         6, 0, 2, 4, 1,      /* Dance Preset */
     65                                         0, 0, 0, 0, 0,      /* Flat Preset */
     66                                         3, 0, 0, 2, -1,     /* Folk Preset */
     67                                         4, 1, 9, 3, 0,      /* Heavy Metal Preset */
     68                                         5, 3, 0, 1, 3,      /* Hip Hop Preset */
     69                                         4, 2, -2, 2, 5,     /* Jazz Preset */
     70                                        -1, 2, 5, 1, -2,     /* Pop Preset */
     71                                         5, 3, -1, 3, 5};    /* Rock Preset */
     72 
     73 const uint16_t equalizer_band_presets_freq[NUM_EQ_BANDS] = {
     74                                         60,      /* Frequencies in Hz */
     75                                         230,
     76                                         910,
     77                                         3600,
     78                                         14000
     79 };
     80 
     81 /*
     82  * Equalizer operations
     83  */
     84 
     85 int equalizer_get_band_level(equalizer_context_t *context, int32_t band)
     86 {
     87     ALOGV("%s: band: %d level: %d", __func__, band,
     88            context->band_levels[band] * 100);
     89     return context->band_levels[band] * 100;
     90 }
     91 
     92 int equalizer_set_band_level(equalizer_context_t *context, int32_t band,
     93                              int32_t level)
     94 {
     95     ALOGV("%s: band: %d, level: %d", __func__, band, level);
     96     if (level > 0) {
     97         level = (int)((level+50)/100);
     98     } else {
     99         level = (int)((level-50)/100);
    100     }
    101     context->band_levels[band] = level;
    102     context->preset = PRESET_CUSTOM;
    103 
    104     offload_eq_set_preset(&(context->offload_eq), PRESET_CUSTOM);
    105     offload_eq_set_bands_level(&(context->offload_eq),
    106                                NUM_EQ_BANDS,
    107                                equalizer_band_presets_freq,
    108                                context->band_levels);
    109     if (context->ctl)
    110         offload_eq_send_params(context->ctl, &context->offload_eq,
    111                                OFFLOAD_SEND_EQ_ENABLE_FLAG |
    112                                OFFLOAD_SEND_EQ_BANDS_LEVEL);
    113     return 0;
    114 }
    115 
    116 int equalizer_get_center_frequency(equalizer_context_t *context __unused, int32_t band)
    117 {
    118     ALOGV("%s: band: %d", __func__, band);
    119     return (equalizer_band_freq_range[band][0] +
    120             equalizer_band_freq_range[band][1]) / 2;
    121 }
    122 
    123 int equalizer_get_band_freq_range(equalizer_context_t *context __unused, int32_t band,
    124                                   uint32_t *low, uint32_t *high)
    125 {
    126     ALOGV("%s: band: %d", __func__, band);
    127     *low = equalizer_band_freq_range[band][0];
    128     *high = equalizer_band_freq_range[band][1];
    129    return 0;
    130 }
    131 
    132 int equalizer_get_band(equalizer_context_t *context __unused, uint32_t freq)
    133 {
    134     int i;
    135 
    136     ALOGV("%s: freq: %d", __func__, freq);
    137     for (i = 0; i < NUM_EQ_BANDS; i++) {
    138         if (freq <= equalizer_band_freq_range[i][1]) {
    139             return i;
    140         }
    141     }
    142     return NUM_EQ_BANDS - 1;
    143 }
    144 
    145 int equalizer_get_preset(equalizer_context_t *context)
    146 {
    147     ALOGV("%s: preset: %d", __func__, context->preset);
    148     return context->preset;
    149 }
    150 
    151 int equalizer_set_preset(equalizer_context_t *context, int preset)
    152 {
    153     int i;
    154 
    155     ALOGV("%s: preset: %d", __func__, preset);
    156     context->preset = preset;
    157     for (i=0; i<NUM_EQ_BANDS; i++)
    158         context->band_levels[i] =
    159                  equalizer_band_presets_level[i + preset * NUM_EQ_BANDS];
    160 
    161     offload_eq_set_preset(&(context->offload_eq), preset);
    162     offload_eq_set_bands_level(&(context->offload_eq),
    163                                NUM_EQ_BANDS,
    164                                equalizer_band_presets_freq,
    165                                context->band_levels);
    166     if(context->ctl)
    167         offload_eq_send_params(context->ctl, &context->offload_eq,
    168                                OFFLOAD_SEND_EQ_ENABLE_FLAG |
    169                                OFFLOAD_SEND_EQ_PRESET);
    170     return 0;
    171 }
    172 
    173 const char * equalizer_get_preset_name(equalizer_context_t *context __unused,
    174                                        int32_t preset)
    175 {
    176     ALOGV("%s: preset: %s", __func__, equalizer_preset_names[preset]);
    177     if (preset == PRESET_CUSTOM) {
    178         return "Custom";
    179     } else {
    180         return equalizer_preset_names[preset];
    181     }
    182 }
    183 
    184 int equalizer_get_num_presets(equalizer_context_t *context __unused)
    185 {
    186     ALOGV("%s: presets_num: %zu", __func__,
    187            sizeof(equalizer_preset_names)/sizeof(char *));
    188     return sizeof(equalizer_preset_names)/sizeof(char *);
    189 }
    190 
    191 int equalizer_get_parameter(effect_context_t *context, effect_param_t *p,
    192                             uint32_t *size)
    193 {
    194     equalizer_context_t *eq_ctxt = (equalizer_context_t *)context;
    195     int voffset = ((p->psize - 1) / sizeof(int32_t) + 1) * sizeof(int32_t);
    196     int32_t *param_tmp = (int32_t *)p->data;
    197     int32_t param = *param_tmp++;
    198     int32_t param2;
    199     char *name;
    200     void *value = p->data + voffset;
    201     int i;
    202 
    203     ALOGV("%s", __func__);
    204 
    205     p->status = 0;
    206 
    207     switch (param) {
    208     case EQ_PARAM_NUM_BANDS:
    209     case EQ_PARAM_CUR_PRESET:
    210     case EQ_PARAM_GET_NUM_OF_PRESETS:
    211     case EQ_PARAM_BAND_LEVEL:
    212     case EQ_PARAM_GET_BAND:
    213         if (p->vsize < sizeof(int16_t))
    214            p->status = -EINVAL;
    215         p->vsize = sizeof(int16_t);
    216         break;
    217 
    218     case EQ_PARAM_LEVEL_RANGE:
    219         if (p->vsize < 2 * sizeof(int16_t))
    220             p->status = -EINVAL;
    221         p->vsize = 2 * sizeof(int16_t);
    222         break;
    223     case EQ_PARAM_BAND_FREQ_RANGE:
    224        if (p->vsize < 2 * sizeof(int32_t))
    225             p->status = -EINVAL;
    226         p->vsize = 2 * sizeof(int32_t);
    227         break;
    228 
    229    case EQ_PARAM_CENTER_FREQ:
    230         if (p->vsize < sizeof(int32_t))
    231             p->status = -EINVAL;
    232         p->vsize = sizeof(int32_t);
    233         break;
    234 
    235     case EQ_PARAM_GET_PRESET_NAME:
    236         break;
    237 
    238     case EQ_PARAM_PROPERTIES:
    239         if (p->vsize < (2 + NUM_EQ_BANDS) * sizeof(uint16_t))
    240             p->status = -EINVAL;
    241         p->vsize = (2 + NUM_EQ_BANDS) * sizeof(uint16_t);
    242         break;
    243 
    244     default:
    245         p->status = -EINVAL;
    246     }
    247 
    248     *size = sizeof(effect_param_t) + voffset + p->vsize;
    249 
    250     if (p->status != 0)
    251         return 0;
    252 
    253     switch (param) {
    254     case EQ_PARAM_NUM_BANDS:
    255 	ALOGV("%s: EQ_PARAM_NUM_BANDS", __func__);
    256         *(uint16_t *)value = (uint16_t)NUM_EQ_BANDS;
    257         break;
    258 
    259     case EQ_PARAM_LEVEL_RANGE:
    260 	ALOGV("%s: EQ_PARAM_LEVEL_RANGE", __func__);
    261         *(int16_t *)value = -1500;
    262         *((int16_t *)value + 1) = 1500;
    263         break;
    264 
    265     case EQ_PARAM_BAND_LEVEL:
    266 	ALOGV("%s: EQ_PARAM_BAND_LEVEL", __func__);
    267         param2 = *param_tmp;
    268         if (param2 < 0 || param2 >= NUM_EQ_BANDS) {
    269             p->status = -EINVAL;
    270             if (param2 < 0) {
    271                 android_errorWriteLog(0x534e4554, "32438598");
    272                 ALOGW("\tERROR EQ_PARAM_BAND_LEVEL band %d", param2);
    273             }
    274             break;
    275         }
    276         *(int16_t *)value = (int16_t)equalizer_get_band_level(eq_ctxt, param2);
    277         break;
    278 
    279     case EQ_PARAM_CENTER_FREQ:
    280 	ALOGV("%s: EQ_PARAM_CENTER_FREQ", __func__);
    281         param2 = *param_tmp;
    282         if (param2 < 0 || param2 >= NUM_EQ_BANDS) {
    283             p->status = -EINVAL;
    284             if (param2 < 0) {
    285                 android_errorWriteLog(0x534e4554, "32436341");
    286                 ALOGW("\tERROR EQ_PARAM_CENTER_FREQ band %d", param2);
    287             }
    288             break;
    289         }
    290         *(int32_t *)value = equalizer_get_center_frequency(eq_ctxt, param2);
    291         break;
    292 
    293     case EQ_PARAM_BAND_FREQ_RANGE:
    294 	ALOGV("%s: EQ_PARAM_BAND_FREQ_RANGE", __func__);
    295         param2 = *param_tmp;
    296         if (param2 < 0 || param2 >= NUM_EQ_BANDS) {
    297             p->status = -EINVAL;
    298             if (param2 < 0) {
    299                 android_errorWriteLog(0x534e4554, "32247948");
    300                 ALOGW("\tERROR EQ_PARAM_BAND_FREQ_RANGE band %d", param2);
    301             }
    302            break;
    303         }
    304        equalizer_get_band_freq_range(eq_ctxt, param2, (uint32_t *)value,
    305                                      ((uint32_t *)value + 1));
    306         break;
    307 
    308     case EQ_PARAM_GET_BAND:
    309 	ALOGV("%s: EQ_PARAM_GET_BAND", __func__);
    310         param2 = *param_tmp;
    311         *(uint16_t *)value = (uint16_t)equalizer_get_band(eq_ctxt, param2);
    312         break;
    313 
    314     case EQ_PARAM_CUR_PRESET:
    315 	ALOGV("%s: EQ_PARAM_CUR_PRESET", __func__);
    316         *(uint16_t *)value = (uint16_t)equalizer_get_preset(eq_ctxt);
    317         break;
    318 
    319     case EQ_PARAM_GET_NUM_OF_PRESETS:
    320 	ALOGV("%s: EQ_PARAM_GET_NUM_OF_PRESETS", __func__);
    321         *(uint16_t *)value = (uint16_t)equalizer_get_num_presets(eq_ctxt);
    322         break;
    323 
    324     case EQ_PARAM_GET_PRESET_NAME:
    325 	ALOGV("%s: EQ_PARAM_GET_PRESET_NAME", __func__);
    326         param2 = *param_tmp;
    327 	ALOGV("param2: %d", param2);
    328         if ((param2 < 0 && param2 != PRESET_CUSTOM) ||
    329             param2 >= equalizer_get_num_presets(eq_ctxt)) {
    330                 p->status = -EINVAL;
    331                 if (param2 < 0) {
    332                     android_errorWriteLog(0x534e4554, "32588016");
    333                     ALOGW("\tERROR EQ_PARAM_GET_PRESET_NAME preset %d", param2);
    334                 }
    335                 break;
    336         }
    337 
    338         if (p->vsize < 1) {
    339             p->status = -EINVAL;
    340             android_errorWriteLog(0x534e4554, "37536407");
    341             break;
    342         }
    343 
    344         name = (char *)value;
    345         strlcpy(name, equalizer_get_preset_name(eq_ctxt, param2), p->vsize - 1);
    346         name[p->vsize - 1] = 0;
    347         p->vsize = strlen(name) + 1;
    348         break;
    349 
    350     case EQ_PARAM_PROPERTIES: {
    351 	ALOGV("%s: EQ_PARAM_PROPERTIES", __func__);
    352         int16_t *prop = (int16_t *)value;
    353         prop[0] = (int16_t)equalizer_get_preset(eq_ctxt);
    354         prop[1] = (int16_t)NUM_EQ_BANDS;
    355         for (i = 0; i < NUM_EQ_BANDS; i++) {
    356             prop[2 + i] = (int16_t)equalizer_get_band_level(eq_ctxt, i);
    357         }
    358     } break;
    359 
    360     default:
    361         p->status = -EINVAL;
    362         break;
    363     }
    364 
    365     return 0;
    366 }
    367 
    368 int equalizer_set_parameter(effect_context_t *context, effect_param_t *p,
    369                             uint32_t size __unused)
    370 {
    371     equalizer_context_t *eq_ctxt = (equalizer_context_t *)context;
    372     int voffset = ((p->psize - 1) / sizeof(int32_t) + 1) * sizeof(int32_t);
    373     void *value = p->data + voffset;
    374     int32_t vsize = (int32_t) p->vsize;
    375     int32_t *param_tmp = (int32_t *)p->data;
    376     int32_t param = *param_tmp++;
    377     int32_t preset;
    378     int32_t band;
    379     int32_t level;
    380     int i;
    381 
    382     ALOGV("%s", __func__);
    383 
    384     p->status = 0;
    385 
    386     switch (param) {
    387     case EQ_PARAM_CUR_PRESET:
    388 	ALOGV("EQ_PARAM_CUR_PRESET");
    389         if (vsize < sizeof(int16_t)) {
    390            p->status = -EINVAL;
    391            break;
    392         }
    393         preset = (int32_t)(*(uint16_t *)value);
    394 
    395         if ((preset >= equalizer_get_num_presets(eq_ctxt)) || (preset < 0)) {
    396            p->status = -EINVAL;
    397             break;
    398         }
    399         equalizer_set_preset(eq_ctxt, preset);
    400         break;
    401     case EQ_PARAM_BAND_LEVEL:
    402 	ALOGV("EQ_PARAM_BAND_LEVEL");
    403         if (vsize < sizeof(int16_t)) {
    404             p->status = -EINVAL;
    405             break;
    406         }
    407         band =  *param_tmp;
    408         level = (int32_t)(*(int16_t *)value);
    409         if (band < 0 || band >= NUM_EQ_BANDS) {
    410             p->status = -EINVAL;
    411             if (band < 0) {
    412                 android_errorWriteLog(0x534e4554, "32585400");
    413                 ALOGW("\tERROR EQ_PARAM_BAND_LEVEL band %d", band);
    414             }
    415             break;
    416         }
    417         equalizer_set_band_level(eq_ctxt, band, level);
    418         break;
    419     case EQ_PARAM_PROPERTIES: {
    420 	ALOGV("EQ_PARAM_PROPERTIES");
    421         if (vsize < sizeof(int16_t)) {
    422             p->status = -EINVAL;
    423             break;
    424         }
    425         int16_t *prop = (int16_t *)value;
    426         if ((int)prop[0] >= equalizer_get_num_presets(eq_ctxt)) {
    427             p->status = -EINVAL;
    428             break;
    429         }
    430         if (prop[0] >= 0) {
    431             equalizer_set_preset(eq_ctxt, (int)prop[0]);
    432         } else {
    433             if (vsize < (2 + NUM_EQ_BANDS) * sizeof(int16_t)) {
    434                 android_errorWriteLog(0x534e4554, "37563371");
    435                 ALOGE("\tERROR EQ_PARAM_PROPERTIES valueSize %d < %d",
    436                                   vsize, (2 + NUM_EQ_BANDS) * sizeof(int16_t));
    437                 p->status = -EINVAL;
    438                 break;
    439             }
    440             if ((int)prop[1] != NUM_EQ_BANDS) {
    441                 p->status = -EINVAL;
    442                 break;
    443             }
    444             for (i = 0; i < NUM_EQ_BANDS; i++) {
    445                equalizer_set_band_level(eq_ctxt, i, (int)prop[2 + i]);
    446             }
    447         }
    448     } break;
    449     default:
    450         p->status = -EINVAL;
    451         break;
    452     }
    453 
    454     return 0;
    455 }
    456 
    457 int equalizer_set_device(effect_context_t *context,  uint32_t device)
    458 {
    459     ALOGV("%s: device: %d", __func__, device);
    460     equalizer_context_t *eq_ctxt = (equalizer_context_t *)context;
    461     eq_ctxt->device = device;
    462     offload_eq_set_device(&(eq_ctxt->offload_eq), device);
    463     return 0;
    464 }
    465 
    466 int equalizer_reset(effect_context_t *context)
    467 {
    468     equalizer_context_t *eq_ctxt = (equalizer_context_t *)context;
    469 
    470     return 0;
    471 }
    472 
    473 int equalizer_init(effect_context_t *context)
    474 {
    475     ALOGV("%s", __func__);
    476     equalizer_context_t *eq_ctxt = (equalizer_context_t *)context;
    477 
    478     context->config.inputCfg.accessMode = EFFECT_BUFFER_ACCESS_READ;
    479     context->config.inputCfg.channels = AUDIO_CHANNEL_OUT_STEREO;
    480     context->config.inputCfg.format = AUDIO_FORMAT_PCM_16_BIT;
    481     context->config.inputCfg.samplingRate = 44100;
    482     context->config.inputCfg.bufferProvider.getBuffer = NULL;
    483     context->config.inputCfg.bufferProvider.releaseBuffer = NULL;
    484     context->config.inputCfg.bufferProvider.cookie = NULL;
    485     context->config.inputCfg.mask = EFFECT_CONFIG_ALL;
    486     context->config.outputCfg.accessMode = EFFECT_BUFFER_ACCESS_ACCUMULATE;
    487     context->config.outputCfg.channels = AUDIO_CHANNEL_OUT_STEREO;
    488     context->config.outputCfg.format = AUDIO_FORMAT_PCM_16_BIT;
    489     context->config.outputCfg.samplingRate = 44100;
    490     context->config.outputCfg.bufferProvider.getBuffer = NULL;
    491     context->config.outputCfg.bufferProvider.releaseBuffer = NULL;
    492     context->config.outputCfg.bufferProvider.cookie = NULL;
    493     context->config.outputCfg.mask = EFFECT_CONFIG_ALL;
    494 
    495     set_config(context, &context->config);
    496 
    497     memset(&(eq_ctxt->offload_eq), 0, sizeof(struct eq_params));
    498     offload_eq_set_preset(&(eq_ctxt->offload_eq), INVALID_PRESET);
    499 
    500     return 0;
    501 }
    502 
    503 int equalizer_enable(effect_context_t *context)
    504 {
    505     equalizer_context_t *eq_ctxt = (equalizer_context_t *)context;
    506 
    507     ALOGV("%s", __func__);
    508 
    509     if (!offload_eq_get_enable_flag(&(eq_ctxt->offload_eq))) {
    510         offload_eq_set_enable_flag(&(eq_ctxt->offload_eq), true);
    511         if (eq_ctxt->ctl)
    512             offload_eq_send_params(eq_ctxt->ctl, &eq_ctxt->offload_eq,
    513                                    OFFLOAD_SEND_EQ_ENABLE_FLAG |
    514                                    OFFLOAD_SEND_EQ_BANDS_LEVEL);
    515     }
    516     return 0;
    517 }
    518 
    519 int equalizer_disable(effect_context_t *context)
    520 {
    521     equalizer_context_t *eq_ctxt = (equalizer_context_t *)context;
    522 
    523     ALOGV("%s", __func__);
    524     if (offload_eq_get_enable_flag(&(eq_ctxt->offload_eq))) {
    525         offload_eq_set_enable_flag(&(eq_ctxt->offload_eq), false);
    526         if (eq_ctxt->ctl)
    527             offload_eq_send_params(eq_ctxt->ctl, &eq_ctxt->offload_eq,
    528                                    OFFLOAD_SEND_EQ_ENABLE_FLAG);
    529     }
    530     return 0;
    531 }
    532 
    533 int equalizer_start(effect_context_t *context, output_context_t *output)
    534 {
    535     equalizer_context_t *eq_ctxt = (equalizer_context_t *)context;
    536 
    537     ALOGV("%s: %p", __func__, output->ctl);
    538     eq_ctxt->ctl = output->ctl;
    539     if (offload_eq_get_enable_flag(&(eq_ctxt->offload_eq)))
    540         if (eq_ctxt->ctl)
    541             offload_eq_send_params(eq_ctxt->ctl, &eq_ctxt->offload_eq,
    542                                    OFFLOAD_SEND_EQ_ENABLE_FLAG |
    543                                    OFFLOAD_SEND_EQ_BANDS_LEVEL);
    544     return 0;
    545 }
    546 
    547 int equalizer_stop(effect_context_t *context, output_context_t *output __unused)
    548 {
    549     equalizer_context_t *eq_ctxt = (equalizer_context_t *)context;
    550 
    551     ALOGV("%s", __func__);
    552     eq_ctxt->ctl = NULL;
    553     return 0;
    554 }
    555