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),
     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: %d", __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 >= NUM_EQ_BANDS) {
    269             p->status = -EINVAL;
    270             break;
    271         }
    272         *(int16_t *)value = (int16_t)equalizer_get_band_level(eq_ctxt, param2);
    273         break;
    274 
    275     case EQ_PARAM_CENTER_FREQ:
    276 	ALOGV("%s: EQ_PARAM_CENTER_FREQ", __func__);
    277         param2 = *param_tmp;
    278         if (param2 >= NUM_EQ_BANDS) {
    279            p->status = -EINVAL;
    280             break;
    281         }
    282         *(int32_t *)value = equalizer_get_center_frequency(eq_ctxt, param2);
    283         break;
    284 
    285     case EQ_PARAM_BAND_FREQ_RANGE:
    286 	ALOGV("%s: EQ_PARAM_BAND_FREQ_RANGE", __func__);
    287         param2 = *param_tmp;
    288         if (param2 >= NUM_EQ_BANDS) {
    289             p->status = -EINVAL;
    290            break;
    291         }
    292        equalizer_get_band_freq_range(eq_ctxt, param2, (uint32_t *)value,
    293                                      ((uint32_t *)value + 1));
    294         break;
    295 
    296     case EQ_PARAM_GET_BAND:
    297 	ALOGV("%s: EQ_PARAM_GET_BAND", __func__);
    298         param2 = *param_tmp;
    299         *(uint16_t *)value = (uint16_t)equalizer_get_band(eq_ctxt, param2);
    300         break;
    301 
    302     case EQ_PARAM_CUR_PRESET:
    303 	ALOGV("%s: EQ_PARAM_CUR_PRESET", __func__);
    304         *(uint16_t *)value = (uint16_t)equalizer_get_preset(eq_ctxt);
    305         break;
    306 
    307     case EQ_PARAM_GET_NUM_OF_PRESETS:
    308 	ALOGV("%s: EQ_PARAM_GET_NUM_OF_PRESETS", __func__);
    309         *(uint16_t *)value = (uint16_t)equalizer_get_num_presets(eq_ctxt);
    310         break;
    311 
    312     case EQ_PARAM_GET_PRESET_NAME:
    313 	ALOGV("%s: EQ_PARAM_GET_PRESET_NAME", __func__);
    314         param2 = *param_tmp;
    315 	ALOGV("param2: %d", param2);
    316         if (param2 >= equalizer_get_num_presets(eq_ctxt)) {
    317             p->status = -EINVAL;
    318             break;
    319         }
    320         name = (char *)value;
    321         strlcpy(name, equalizer_get_preset_name(eq_ctxt, param2), p->vsize - 1);
    322         name[p->vsize - 1] = 0;
    323         p->vsize = strlen(name) + 1;
    324         break;
    325 
    326     case EQ_PARAM_PROPERTIES: {
    327 	ALOGV("%s: EQ_PARAM_PROPERTIES", __func__);
    328         int16_t *prop = (int16_t *)value;
    329         prop[0] = (int16_t)equalizer_get_preset(eq_ctxt);
    330         prop[1] = (int16_t)NUM_EQ_BANDS;
    331         for (i = 0; i < NUM_EQ_BANDS; i++) {
    332             prop[2 + i] = (int16_t)equalizer_get_band_level(eq_ctxt, i);
    333         }
    334     } break;
    335 
    336     default:
    337         p->status = -EINVAL;
    338         break;
    339     }
    340 
    341     return 0;
    342 }
    343 
    344 int equalizer_set_parameter(effect_context_t *context, effect_param_t *p,
    345                             uint32_t size __unused)
    346 {
    347     equalizer_context_t *eq_ctxt = (equalizer_context_t *)context;
    348     int voffset = ((p->psize - 1) / sizeof(int32_t) + 1) * sizeof(int32_t);
    349     void *value = p->data + voffset;
    350     int32_t *param_tmp = (int32_t *)p->data;
    351     int32_t param = *param_tmp++;
    352     int32_t preset;
    353     int32_t band;
    354     int32_t level;
    355     int i;
    356 
    357     ALOGV("%s", __func__);
    358 
    359     p->status = 0;
    360 
    361     switch (param) {
    362     case EQ_PARAM_CUR_PRESET:
    363 	ALOGV("EQ_PARAM_CUR_PRESET");
    364         preset = (int32_t)(*(uint16_t *)value);
    365 
    366         if ((preset >= equalizer_get_num_presets(eq_ctxt)) || (preset < 0)) {
    367            p->status = -EINVAL;
    368             break;
    369         }
    370         equalizer_set_preset(eq_ctxt, preset);
    371         break;
    372     case EQ_PARAM_BAND_LEVEL:
    373 	ALOGV("EQ_PARAM_BAND_LEVEL");
    374         band =  *param_tmp;
    375         level = (int32_t)(*(int16_t *)value);
    376         if (band >= NUM_EQ_BANDS) {
    377            p->status = -EINVAL;
    378             break;
    379         }
    380         equalizer_set_band_level(eq_ctxt, band, level);
    381         break;
    382     case EQ_PARAM_PROPERTIES: {
    383 	ALOGV("EQ_PARAM_PROPERTIES");
    384         int16_t *prop = (int16_t *)value;
    385         if ((int)prop[0] >= equalizer_get_num_presets(eq_ctxt)) {
    386             p->status = -EINVAL;
    387             break;
    388         }
    389         if (prop[0] >= 0) {
    390             equalizer_set_preset(eq_ctxt, (int)prop[0]);
    391         } else {
    392             if ((int)prop[1] != NUM_EQ_BANDS) {
    393                 p->status = -EINVAL;
    394                 break;
    395             }
    396             for (i = 0; i < NUM_EQ_BANDS; i++) {
    397                equalizer_set_band_level(eq_ctxt, i, (int)prop[2 + i]);
    398             }
    399         }
    400     } break;
    401     default:
    402         p->status = -EINVAL;
    403         break;
    404     }
    405 
    406     return 0;
    407 }
    408 
    409 int equalizer_set_device(effect_context_t *context,  uint32_t device)
    410 {
    411     ALOGV("%s: device: %d", __func__, device);
    412     equalizer_context_t *eq_ctxt = (equalizer_context_t *)context;
    413     eq_ctxt->device = device;
    414     offload_eq_set_device(&(eq_ctxt->offload_eq), device);
    415     return 0;
    416 }
    417 
    418 int equalizer_reset(effect_context_t *context)
    419 {
    420     equalizer_context_t *eq_ctxt = (equalizer_context_t *)context;
    421 
    422     return 0;
    423 }
    424 
    425 int equalizer_init(effect_context_t *context)
    426 {
    427     ALOGV("%s", __func__);
    428     equalizer_context_t *eq_ctxt = (equalizer_context_t *)context;
    429 
    430     context->config.inputCfg.accessMode = EFFECT_BUFFER_ACCESS_READ;
    431     context->config.inputCfg.channels = AUDIO_CHANNEL_OUT_STEREO;
    432     context->config.inputCfg.format = AUDIO_FORMAT_PCM_16_BIT;
    433     context->config.inputCfg.samplingRate = 44100;
    434     context->config.inputCfg.bufferProvider.getBuffer = NULL;
    435     context->config.inputCfg.bufferProvider.releaseBuffer = NULL;
    436     context->config.inputCfg.bufferProvider.cookie = NULL;
    437     context->config.inputCfg.mask = EFFECT_CONFIG_ALL;
    438     context->config.outputCfg.accessMode = EFFECT_BUFFER_ACCESS_ACCUMULATE;
    439     context->config.outputCfg.channels = AUDIO_CHANNEL_OUT_STEREO;
    440     context->config.outputCfg.format = AUDIO_FORMAT_PCM_16_BIT;
    441     context->config.outputCfg.samplingRate = 44100;
    442     context->config.outputCfg.bufferProvider.getBuffer = NULL;
    443     context->config.outputCfg.bufferProvider.releaseBuffer = NULL;
    444     context->config.outputCfg.bufferProvider.cookie = NULL;
    445     context->config.outputCfg.mask = EFFECT_CONFIG_ALL;
    446 
    447     set_config(context, &context->config);
    448 
    449     memset(&(eq_ctxt->offload_eq), 0, sizeof(struct eq_params));
    450     offload_eq_set_preset(&(eq_ctxt->offload_eq), INVALID_PRESET);
    451 
    452     return 0;
    453 }
    454 
    455 int equalizer_enable(effect_context_t *context)
    456 {
    457     equalizer_context_t *eq_ctxt = (equalizer_context_t *)context;
    458 
    459     ALOGV("%s", __func__);
    460 
    461     if (!offload_eq_get_enable_flag(&(eq_ctxt->offload_eq))) {
    462         offload_eq_set_enable_flag(&(eq_ctxt->offload_eq), true);
    463         if (eq_ctxt->ctl)
    464             offload_eq_send_params(eq_ctxt->ctl, &eq_ctxt->offload_eq,
    465                                    OFFLOAD_SEND_EQ_ENABLE_FLAG |
    466                                    OFFLOAD_SEND_EQ_BANDS_LEVEL);
    467     }
    468     return 0;
    469 }
    470 
    471 int equalizer_disable(effect_context_t *context)
    472 {
    473     equalizer_context_t *eq_ctxt = (equalizer_context_t *)context;
    474 
    475     ALOGV("%s", __func__);
    476     if (offload_eq_get_enable_flag(&(eq_ctxt->offload_eq))) {
    477         offload_eq_set_enable_flag(&(eq_ctxt->offload_eq), false);
    478         if (eq_ctxt->ctl)
    479             offload_eq_send_params(eq_ctxt->ctl, &eq_ctxt->offload_eq,
    480                                    OFFLOAD_SEND_EQ_ENABLE_FLAG);
    481     }
    482     return 0;
    483 }
    484 
    485 int equalizer_start(effect_context_t *context, output_context_t *output)
    486 {
    487     equalizer_context_t *eq_ctxt = (equalizer_context_t *)context;
    488 
    489     ALOGV("%s: %p", __func__, output->ctl);
    490     eq_ctxt->ctl = output->ctl;
    491     if (offload_eq_get_enable_flag(&(eq_ctxt->offload_eq)))
    492         if (eq_ctxt->ctl)
    493             offload_eq_send_params(eq_ctxt->ctl, &eq_ctxt->offload_eq,
    494                                    OFFLOAD_SEND_EQ_ENABLE_FLAG |
    495                                    OFFLOAD_SEND_EQ_BANDS_LEVEL);
    496     return 0;
    497 }
    498 
    499 int equalizer_stop(effect_context_t *context, output_context_t *output __unused)
    500 {
    501     equalizer_context_t *eq_ctxt = (equalizer_context_t *)context;
    502 
    503     ALOGV("%s", __func__);
    504     eq_ctxt->ctl = NULL;
    505     return 0;
    506 }
    507