19c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid/* Copyright (c) 2012 The Chromium OS Authors. All rights reserved. 29c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid * Use of this source code is governed by a BSD-style license that can be 39c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid * found in the LICENSE file. 49c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid */ 59c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid 69c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid#include <cutils/log.h> 79c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid#include <semaphore.h> 89c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid#include "cras_expr.h" 99c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid#include "cras_dsp_ini.h" 109c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid#include "cras_dsp_pipeline.h" 119c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid#include "dsp_util.h" 129c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid#include "utlist.h" 139c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid 149c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid#define LOG_TAG "audio_cras_dsp" 159c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid 169c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid/* We have a dsp_context for each pipeline. The context records the 179c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid * parameters used to create a pipeline, so the pipeline can be 189c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid * (re-)loaded later. The pipeline is (re-)loaded in the following 199c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid * cases: 209c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid * 219c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid * (1) The client asks to (re-)load it with cras_load_pipeline(). 229c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid * (2) The client asks to reload the ini with cras_reload_ini(). 239c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid * 249c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid */ 259c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reidstruct cras_dsp_context { 269c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid struct pipeline *pipeline; 279c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid 289c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid struct cras_expr_env env; 299c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid int sample_rate; 309c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid const char *purpose; 319c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid struct cras_dsp_context *prev, *next; 329c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid}; 339c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid 349c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reidstatic const char *ini_filename; 359c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reidstatic struct ini *ini; 369c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reidstatic struct cras_dsp_context *context_list; 379c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid 389c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reidstatic void initialize_environment(struct cras_expr_env *env) 399c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid{ 409c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid cras_expr_env_install_builtins(env); 419c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid cras_expr_env_set_variable_boolean(env, "disable_eq", 0); 429c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid cras_expr_env_set_variable_boolean(env, "disable_drc", 0); 439c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid cras_expr_env_set_variable_string(env, "dsp_name", ""); 449c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid} 459c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid 469c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reidstatic struct pipeline *prepare_pipeline(struct cras_dsp_context *ctx) 479c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid{ 489c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid struct pipeline *pipeline; 499c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid const char *purpose = ctx->purpose; 509c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid 519c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid if (!ini) 529c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid return NULL; 539c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid 549c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid pipeline = cras_dsp_pipeline_create(ini, &ctx->env, purpose); 559c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid 569c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid if (pipeline) { 57e4ad4b7a4f64de6721fff11ae0b57a7267279468Dylan Reid ALOGI("pipeline created"); 589c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid } else { 59e4ad4b7a4f64de6721fff11ae0b57a7267279468Dylan Reid ALOGI("cannot create pipeline"); 609c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid goto bail; 619c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid } 629c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid 639c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid if (cras_dsp_pipeline_load(pipeline) != 0) { 649c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid ALOGE("cannot load pipeline"); 659c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid goto bail; 669c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid } 679c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid 689c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid if (cras_dsp_pipeline_instantiate(pipeline, ctx->sample_rate) != 0) { 699c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid ALOGE("cannot instantiate pipeline"); 709c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid goto bail; 719c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid } 729c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid 739c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid if (cras_dsp_pipeline_get_sample_rate(pipeline) != ctx->sample_rate) { 749c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid ALOGE("pipeline sample rate mismatch (%d vs %d)", 759c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid cras_dsp_pipeline_get_sample_rate(pipeline), 769c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid ctx->sample_rate); 779c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid goto bail; 789c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid } 799c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid 809c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid return pipeline; 819c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid 829c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reidbail: 839c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid if (pipeline) 849c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid cras_dsp_pipeline_free(pipeline); 859c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid return NULL; 869c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid} 879c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid 889c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid/* Exported functions */ 899c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reidvoid cras_dsp_set_variable(struct cras_dsp_context *ctx, const char *key, 909c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid const char *value) 919c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid{ 929c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid cras_expr_env_set_variable_string(&ctx->env, key, value); 939c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid} 949c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid 959c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reidvoid cras_dsp_load_pipeline(struct cras_dsp_context *ctx) 969c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid{ 979c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid struct pipeline *pipeline, *old_pipeline; 989c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid 999c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid pipeline = prepare_pipeline(ctx); 1009c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid 1019c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid old_pipeline = ctx->pipeline; 1029c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid ctx->pipeline = pipeline; 1039c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid 1049c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid if (old_pipeline) 1059c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid cras_dsp_pipeline_free(old_pipeline); 1069c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid} 1079c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid 1089c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reidvoid cras_dsp_reload_ini() 1099c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid{ 1109c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid struct ini *old_ini = ini; 1119c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid struct cras_dsp_context *ctx; 1129c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid 1139c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid ini = cras_dsp_ini_create(ini_filename); 1149c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid if (!ini) 1159c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid ALOGE("cannot create dsp ini"); 1169c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid 1179c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid DL_FOREACH(context_list, ctx) { 1189c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid cras_dsp_load_pipeline(ctx); 1199c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid } 1209c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid 1219c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid if (old_ini) 1229c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid cras_dsp_ini_free(old_ini); 1239c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid} 1249c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid 1259c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reidvoid cras_dsp_init(const char *filename) 1269c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid{ 1279c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid dsp_enable_flush_denormal_to_zero(); 1289c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid ini_filename = strdup(filename); 1299c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid cras_dsp_reload_ini(); 1309c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid} 1319c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid 1329c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reidvoid cras_dsp_stop() 1339c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid{ 1349c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid free((char *)ini_filename); 1359c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid if (ini) { 1369c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid cras_dsp_ini_free(ini); 1379c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid ini = NULL; 1389c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid } 1399c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid} 1409c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid 1419c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reidstruct cras_dsp_context *cras_dsp_context_new(int sample_rate, 1429c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid const char *purpose) 1439c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid{ 1449c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid struct cras_dsp_context *ctx = calloc(1, sizeof(*ctx)); 1459c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid 1469c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid initialize_environment(&ctx->env); 1479c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid ctx->sample_rate = sample_rate; 1489c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid ctx->purpose = strdup(purpose); 1499c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid 1509c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid DL_APPEND(context_list, ctx); 1519c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid return ctx; 1529c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid} 1539c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid 1549c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reidvoid cras_dsp_context_free(struct cras_dsp_context *ctx) 1559c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid{ 1569c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid DL_DELETE(context_list, ctx); 1579c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid 1589c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid if (ctx->pipeline) { 1599c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid cras_dsp_pipeline_free(ctx->pipeline); 1609c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid ctx->pipeline = NULL; 1619c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid } 1629c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid cras_expr_env_free(&ctx->env); 1639c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid free((char *)ctx->purpose); 1649c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid free(ctx); 1659c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid} 1669c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid 1679c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reidstruct pipeline *cras_dsp_get_pipeline(struct cras_dsp_context *ctx) 1689c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid{ 1699c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid return ctx->pipeline; 1709c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid} 1719c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid 1729c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reidvoid cras_dsp_put_pipeline(struct cras_dsp_context *ctx) 1739c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid{ 1749c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid} 1759c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid 1769c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reidunsigned int cras_dsp_num_output_channels(const struct cras_dsp_context *ctx) 1779c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid{ 1789c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid return cras_dsp_pipeline_get_num_output_channels(ctx->pipeline); 1799c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid} 1809c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid 1819c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reidunsigned int cras_dsp_num_input_channels(const struct cras_dsp_context *ctx) 1829c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid{ 1839c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid return cras_dsp_pipeline_get_num_input_channels(ctx->pipeline); 1849c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid} 1859c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid 1869c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reidvoid cras_dsp_sync() 1879c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid{ 1889c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid} 189