1 /* Copyright (c) 2012 The Chromium OS Authors. All rights reserved. 2 * Use of this source code is governed by a BSD-style license that can be 3 * found in the LICENSE file. 4 */ 5 6 #include <cutils/log.h> 7 #include <semaphore.h> 8 #include "cras_expr.h" 9 #include "cras_dsp_ini.h" 10 #include "cras_dsp_pipeline.h" 11 #include "dsp_util.h" 12 #include "utlist.h" 13 14 #define LOG_TAG "audio_cras_dsp" 15 16 /* We have a dsp_context for each pipeline. The context records the 17 * parameters used to create a pipeline, so the pipeline can be 18 * (re-)loaded later. The pipeline is (re-)loaded in the following 19 * cases: 20 * 21 * (1) The client asks to (re-)load it with cras_load_pipeline(). 22 * (2) The client asks to reload the ini with cras_reload_ini(). 23 * 24 */ 25 struct cras_dsp_context { 26 struct pipeline *pipeline; 27 28 struct cras_expr_env env; 29 int sample_rate; 30 const char *purpose; 31 struct cras_dsp_context *prev, *next; 32 }; 33 34 static const char *ini_filename; 35 static struct ini *ini; 36 static struct cras_dsp_context *context_list; 37 38 static void initialize_environment(struct cras_expr_env *env) 39 { 40 cras_expr_env_install_builtins(env); 41 cras_expr_env_set_variable_boolean(env, "disable_eq", 0); 42 cras_expr_env_set_variable_boolean(env, "disable_drc", 0); 43 cras_expr_env_set_variable_string(env, "dsp_name", ""); 44 } 45 46 static struct pipeline *prepare_pipeline(struct cras_dsp_context *ctx) 47 { 48 struct pipeline *pipeline; 49 const char *purpose = ctx->purpose; 50 51 if (!ini) 52 return NULL; 53 54 pipeline = cras_dsp_pipeline_create(ini, &ctx->env, purpose); 55 56 if (pipeline) { 57 ALOGI("pipeline created"); 58 } else { 59 ALOGI("cannot create pipeline"); 60 goto bail; 61 } 62 63 if (cras_dsp_pipeline_load(pipeline) != 0) { 64 ALOGE("cannot load pipeline"); 65 goto bail; 66 } 67 68 if (cras_dsp_pipeline_instantiate(pipeline, ctx->sample_rate) != 0) { 69 ALOGE("cannot instantiate pipeline"); 70 goto bail; 71 } 72 73 if (cras_dsp_pipeline_get_sample_rate(pipeline) != ctx->sample_rate) { 74 ALOGE("pipeline sample rate mismatch (%d vs %d)", 75 cras_dsp_pipeline_get_sample_rate(pipeline), 76 ctx->sample_rate); 77 goto bail; 78 } 79 80 return pipeline; 81 82 bail: 83 if (pipeline) 84 cras_dsp_pipeline_free(pipeline); 85 return NULL; 86 } 87 88 /* Exported functions */ 89 void cras_dsp_set_variable(struct cras_dsp_context *ctx, const char *key, 90 const char *value) 91 { 92 cras_expr_env_set_variable_string(&ctx->env, key, value); 93 } 94 95 void cras_dsp_load_pipeline(struct cras_dsp_context *ctx) 96 { 97 struct pipeline *pipeline, *old_pipeline; 98 99 pipeline = prepare_pipeline(ctx); 100 101 old_pipeline = ctx->pipeline; 102 ctx->pipeline = pipeline; 103 104 if (old_pipeline) 105 cras_dsp_pipeline_free(old_pipeline); 106 } 107 108 void cras_dsp_reload_ini() 109 { 110 struct ini *old_ini = ini; 111 struct cras_dsp_context *ctx; 112 113 ini = cras_dsp_ini_create(ini_filename); 114 if (!ini) 115 ALOGE("cannot create dsp ini"); 116 117 DL_FOREACH(context_list, ctx) { 118 cras_dsp_load_pipeline(ctx); 119 } 120 121 if (old_ini) 122 cras_dsp_ini_free(old_ini); 123 } 124 125 void cras_dsp_init(const char *filename) 126 { 127 dsp_enable_flush_denormal_to_zero(); 128 ini_filename = strdup(filename); 129 cras_dsp_reload_ini(); 130 } 131 132 void cras_dsp_stop() 133 { 134 free((char *)ini_filename); 135 if (ini) { 136 cras_dsp_ini_free(ini); 137 ini = NULL; 138 } 139 } 140 141 struct cras_dsp_context *cras_dsp_context_new(int sample_rate, 142 const char *purpose) 143 { 144 struct cras_dsp_context *ctx = calloc(1, sizeof(*ctx)); 145 146 initialize_environment(&ctx->env); 147 ctx->sample_rate = sample_rate; 148 ctx->purpose = strdup(purpose); 149 150 DL_APPEND(context_list, ctx); 151 return ctx; 152 } 153 154 void cras_dsp_context_free(struct cras_dsp_context *ctx) 155 { 156 DL_DELETE(context_list, ctx); 157 158 if (ctx->pipeline) { 159 cras_dsp_pipeline_free(ctx->pipeline); 160 ctx->pipeline = NULL; 161 } 162 cras_expr_env_free(&ctx->env); 163 free((char *)ctx->purpose); 164 free(ctx); 165 } 166 167 struct pipeline *cras_dsp_get_pipeline(struct cras_dsp_context *ctx) 168 { 169 return ctx->pipeline; 170 } 171 172 void cras_dsp_put_pipeline(struct cras_dsp_context *ctx) 173 { 174 } 175 176 unsigned int cras_dsp_num_output_channels(const struct cras_dsp_context *ctx) 177 { 178 return cras_dsp_pipeline_get_num_output_channels(ctx->pipeline); 179 } 180 181 unsigned int cras_dsp_num_input_channels(const struct cras_dsp_context *ctx) 182 { 183 return cras_dsp_pipeline_get_num_input_channels(ctx->pipeline); 184 } 185 186 void cras_dsp_sync() 187 { 188 } 189