diff options
Diffstat (limited to 'modules')
-rw-r--r-- | modules/audio/Android.mk | 13 | ||||
-rw-r--r-- | modules/audio/audio_amplifier.c | 146 | ||||
-rw-r--r-- | modules/audio_remote_submix/audio_hw.cpp | 55 | ||||
-rw-r--r-- | modules/sensors/Android.mk | 4 | ||||
-rw-r--r-- | modules/sensors/multihal.cpp | 46 |
5 files changed, 213 insertions, 51 deletions
diff --git a/modules/audio/Android.mk b/modules/audio/Android.mk index ef4b8f5..8dfda57 100644 --- a/modules/audio/Android.mk +++ b/modules/audio/Android.mk @@ -60,3 +60,16 @@ LOCAL_MODULE_TAGS := optional LOCAL_CFLAGS := -Wno-unused-parameter include $(BUILD_SHARED_LIBRARY) + +# The stub audio amplifier HAL module that can be used as a skeleton for +# new implementations. +include $(CLEAR_VARS) + +LOCAL_MODULE := audio_amplifier.default +LOCAL_MODULE_RELATIVE_PATH := hw +LOCAL_SRC_FILES := audio_amplifier.c +LOCAL_SHARED_LIBRARIES := liblog libcutils +LOCAL_MODULE_TAGS := optional +LOCAL_CFLAGS := -Wno-unused-parameter + +include $(BUILD_SHARED_LIBRARY) diff --git a/modules/audio/audio_amplifier.c b/modules/audio/audio_amplifier.c new file mode 100644 index 0000000..9b92356 --- /dev/null +++ b/modules/audio/audio_amplifier.c @@ -0,0 +1,146 @@ +/* + * Copyright (C) 2015 The CyanogenMod Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define LOG_TAG "amplifier_default" +//#define LOG_NDEBUG 0 + +#include <stdint.h> +#include <stdlib.h> +#include <sys/types.h> + +#include <cutils/log.h> +#include <cutils/str_parms.h> + +#include <hardware/audio_amplifier.h> +#include <hardware/hardware.h> + +static int amp_set_input_devices(amplifier_device_t *device, uint32_t devices) +{ + return 0; +} + +static int amp_set_output_devices(amplifier_device_t *device, uint32_t devices) +{ + return 0; +} + +static int amp_enable_output_devices(amplifier_device_t *device, + uint32_t devices, bool enable) +{ + return 0; +} + +static int amp_enable_input_devices(amplifier_device_t *device, + uint32_t devices, bool enable) +{ + return 0; +} + +static int amp_set_mode(amplifier_device_t *device, audio_mode_t mode) +{ + return 0; +} + +static int amp_output_stream_start(amplifier_device_t *device, + struct audio_stream_out *stream, bool offload) +{ + return 0; +} + +static int amp_input_stream_start(amplifier_device_t *device, + struct audio_stream_in *stream) +{ + return 0; +} + +static int amp_output_stream_standby(amplifier_device_t *device, + struct audio_stream_out *stream) +{ + return 0; +} + +static int amp_input_stream_standby(amplifier_device_t *device, + struct audio_stream_in *stream) +{ + return 0; +} + +static int amp_set_parameters(struct amplifier_device *device, + struct str_parms *parms) +{ + return 0; +} + +static int amp_dev_close(hw_device_t *device) +{ + if (device) + free(device); + + return 0; +} + +static int amp_module_open(const hw_module_t *module, const char *name, + hw_device_t **device) +{ + if (strcmp(name, AMPLIFIER_HARDWARE_INTERFACE)) { + ALOGE("%s:%d: %s does not match amplifier hardware interface name\n", + __func__, __LINE__, name); + return -ENODEV; + } + + amplifier_device_t *amp_dev = calloc(1, sizeof(amplifier_device_t)); + if (!amp_dev) { + ALOGE("%s:%d: Unable to allocate memory for amplifier device\n", + __func__, __LINE__); + return -ENOMEM; + } + + amp_dev->common.tag = HARDWARE_DEVICE_TAG; + amp_dev->common.module = (hw_module_t *) module; + amp_dev->common.version = HARDWARE_DEVICE_API_VERSION(1, 0); + amp_dev->common.close = amp_dev_close; + + amp_dev->set_input_devices = amp_set_input_devices; + amp_dev->set_output_devices = amp_set_output_devices; + amp_dev->enable_output_devices = amp_enable_output_devices; + amp_dev->enable_input_devices = amp_enable_input_devices; + amp_dev->set_mode = amp_set_mode; + amp_dev->output_stream_start = amp_output_stream_start; + amp_dev->input_stream_start = amp_input_stream_start; + amp_dev->output_stream_standby = amp_output_stream_standby; + amp_dev->input_stream_standby = amp_input_stream_standby; + amp_dev->set_parameters = amp_set_parameters; + + *device = (hw_device_t *) amp_dev; + + return 0; +} + +static struct hw_module_methods_t hal_module_methods = { + .open = amp_module_open, +}; + +amplifier_module_t HAL_MODULE_INFO_SYM = { + .common = { + .tag = HARDWARE_MODULE_TAG, + .module_api_version = AMPLIFIER_MODULE_API_VERSION_0_1, + .hal_api_version = HARDWARE_HAL_API_VERSION, + .id = AMPLIFIER_HARDWARE_MODULE_ID, + .name = "Default audio amplifier HAL", + .author = "The CyanogenMod Open Source Project", + .methods = &hal_module_methods, + }, +}; diff --git a/modules/audio_remote_submix/audio_hw.cpp b/modules/audio_remote_submix/audio_hw.cpp index ed3d311..515f150 100644 --- a/modules/audio_remote_submix/audio_hw.cpp +++ b/modules/audio_remote_submix/audio_hw.cpp @@ -159,11 +159,11 @@ typedef struct route_config { // destroyed if both and input and output streams are destroyed. struct submix_stream_out *output; struct submix_stream_in *input; -#if ENABLE_RESAMPLING - // Buffer used as temporary storage for resampled data prior to returning data to the output +#if (ENABLE_RESAMPLING || ENABLE_CHANNEL_CONVERSION) + // Buffer used as temporary storage for audio data prior to returning data to the output // stream. - int16_t resampler_buffer[DEFAULT_PIPE_SIZE_IN_FRAMES]; -#endif // ENABLE_RESAMPLING + int16_t processor_buffer[DEFAULT_PIPE_SIZE_IN_FRAMES]; +#endif } route_config_t; struct submix_audio_device { @@ -474,8 +474,8 @@ static void submix_audio_device_release_pipe_l(struct submix_audio_device * cons rsxadev->routes[route_idx].rsxSource = 0; } memset(rsxadev->routes[route_idx].address, 0, AUDIO_DEVICE_MAX_ADDRESS_LEN); -#ifdef ENABLE_RESAMPLING - memset(rsxadev->routes[route_idx].resampler_buffer, 0, +#if (ENABLE_RESAMPLING || ENABLE_CHANNEL_CONVERSION) + memset(rsxadev->routes[route_idx].processor_buffer, 0, sizeof(int16_t) * DEFAULT_PIPE_SIZE_IN_FRAMES); #endif } @@ -1147,13 +1147,14 @@ static ssize_t in_read(struct audio_stream_in *stream, void* buffer, } #endif // ENABLE_CHANNEL_CONVERSION +#if (ENABLE_RESAMPLING || ENABLE_CHANNEL_CONVERSION) + const size_t processor_buffer_size_frames = + sizeof(rsxadev->routes[in->route_handle].processor_buffer) / frame_size; +#endif #if ENABLE_RESAMPLING const uint32_t input_sample_rate = in_get_sample_rate(&stream->common); const uint32_t output_sample_rate = rsxadev->routes[in->route_handle].config.output_sample_rate; - const size_t resampler_buffer_size_frames = - sizeof(rsxadev->routes[in->route_handle].resampler_buffer) / - sizeof(rsxadev->routes[in->route_handle].resampler_buffer[0]); float resampler_ratio = 1.0f; // Determine whether resampling is required. if (input_sample_rate != output_sample_rate) { @@ -1170,16 +1171,18 @@ static ssize_t in_read(struct audio_stream_in *stream, void* buffer, while ((remaining_frames > 0) && (attempts < MAX_READ_ATTEMPTS)) { ssize_t frames_read = -1977; size_t read_frames = remaining_frames; -#if ENABLE_RESAMPLING +#if (ENABLE_RESAMPLING || ENABLE_CHANNEL_CONVERSION) char* const saved_buff = buff; +#endif +#if ENABLE_RESAMPLING if (resampler_ratio != 1.0f) { // Calculate the number of frames from the pipe that need to be read to generate // the data for the input stream read. const size_t frames_required_for_resampler = (size_t)( (float)read_frames * (float)resampler_ratio); - read_frames = min(frames_required_for_resampler, resampler_buffer_size_frames); + read_frames = min(frames_required_for_resampler, processor_buffer_size_frames); // Read into the resampler buffer. - buff = (char*)rsxadev->routes[in->route_handle].resampler_buffer; + buff = (char*)rsxadev->routes[in->route_handle].processor_buffer; } #endif // ENABLE_RESAMPLING #if ENABLE_CHANNEL_CONVERSION @@ -1187,6 +1190,13 @@ static ssize_t in_read(struct audio_stream_in *stream, void* buffer, // Need to read half the requested frames since the converted output // data will take twice the space (mono->stereo). read_frames /= 2; + } else if (output_channels == 2 && input_channels == 1) { + // If the resampler is active, we already swapped for the processor_buffer + if (resampler_ratio == 1.0f) { + buff = (char*)rsxadev->routes[in->route_handle].processor_buffer; + } + + read_frames = min(read_frames, processor_buffer_size_frames/2); } #endif // ENABLE_CHANNEL_CONVERSION @@ -1205,11 +1215,17 @@ static ssize_t in_read(struct audio_stream_in *stream, void* buffer, if (output_channels == 2 && input_channels == 1) { // Offset into the output stream data in samples. ssize_t output_stream_offset = 0; + // If resampler is active, continue writing to the temporary buffer + int16_t *mixed_buffer = + (resampler_ratio == 1.0f) ? (int16_t*)saved_buff : (int16_t*)buff; for (ssize_t input_stream_frame = 0; input_stream_frame < frames_read; input_stream_frame++, output_stream_offset += 2) { // Average the content from both channels. - data[input_stream_frame] = ((int32_t)data[output_stream_offset] + - (int32_t)data[output_stream_offset + 1]) / 2; + mixed_buffer[input_stream_frame] = ((int32_t)data[output_stream_offset] + + (int32_t)data[output_stream_offset + 1]) / 2; + } + if (resampler_ratio == 1.0f) { + buff = saved_buff; } } else if (output_channels == 1 && input_channels == 2) { // Offset into the input stream data in samples. @@ -1233,13 +1249,20 @@ static ssize_t in_read(struct audio_stream_in *stream, void* buffer, // sampled at a different rate this will result in very nasty aliasing. const float output_stream_frames = (float)frames_read; size_t input_stream_frame = 0; + size_t input_buf_offset = 0, output_buf_offset = 0; for (float output_stream_frame = 0.0f; output_stream_frame < output_stream_frames && input_stream_frame < remaining_frames; output_stream_frame += resampler_ratio, input_stream_frame++) { - resampled_buffer[input_stream_frame] = data[(size_t)output_stream_frame]; + input_buf_offset = input_stream_frame * input_channels; + output_buf_offset = (size_t)output_stream_frame * input_channels; + resampled_buffer[input_buf_offset] = data[output_buf_offset]; + if (input_channels == 2) { + // copy second channel in the frame + resampled_buffer[input_buf_offset + 1] = data[output_buf_offset + 1]; + } } - ALOG_ASSERT(input_stream_frame <= (ssize_t)resampler_buffer_size_frames); + ALOG_ASSERT(input_stream_frame <= (ssize_t)processor_buffer_size_frames); SUBMIX_ALOGV("in_read(): resampler produced %zd frames", input_stream_frame); frames_read = input_stream_frame; buff = saved_buff; diff --git a/modules/sensors/Android.mk b/modules/sensors/Android.mk index 445f69e..94d100b 100644 --- a/modules/sensors/Android.mk +++ b/modules/sensors/Android.mk @@ -20,9 +20,9 @@ ifeq ($(USE_SENSOR_MULTI_HAL),true) include $(CLEAR_VARS) -LOCAL_MODULE := sensors.$(TARGET_DEVICE) +LOCAL_MODULE := sensors.$(TARGET_BOARD_PLATFORM) -LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw +LOCAL_MODULE_RELATIVE_PATH := hw LOCAL_CFLAGS := -DLOG_TAG=\"MultiHal\" diff --git a/modules/sensors/multihal.cpp b/modules/sensors/multihal.cpp index d26d168..8330ff3 100644 --- a/modules/sensors/multihal.cpp +++ b/modules/sensors/multihal.cpp @@ -27,6 +27,8 @@ #include <cutils/log.h> #include <vector> +#include <string> +#include <fstream> #include <map> #include <string> @@ -38,8 +40,6 @@ #include <stdlib.h> static const char* CONFIG_FILENAME = "/system/etc/sensors/hals.conf"; -static const char* LEGAL_SUBHAL_PATH_PREFIX = "/system/lib/hw/"; -static const char* LEGAL_SUBHAL_ALTERNATE_PATH_PREFIX = "/system/vendor/lib/"; static const int MAX_CONF_LINE_LENGTH = 1024; static pthread_mutex_t init_modules_mutex = PTHREAD_MUTEX_INITIALIZER; @@ -465,39 +465,19 @@ static bool starts_with(const char* s, const char* prefix) { * Adds valid paths from the config file to the vector passed in. * The vector must not be null. */ -static void get_so_paths(std::vector<char*> *so_paths) { - FILE *conf_file = fopen(CONFIG_FILENAME, "r"); - if (conf_file == NULL) { +static void get_so_paths(std::vector<std::string> *so_paths) { + std::string line; + std::ifstream conf_file(CONFIG_FILENAME); + + if(!conf_file) { ALOGW("No multihal config file found at %s", CONFIG_FILENAME); return; } ALOGV("Multihal config file found at %s", CONFIG_FILENAME); - char *line = NULL; - size_t len = 0; - int line_count = 0; - while (getline(&line, &len, conf_file) != -1) { - // overwrite trailing eoln with null char - char* pch = strchr(line, '\n'); - if (pch != NULL) { - *pch = '\0'; - } - ALOGV("config file line #%d: '%s'", ++line_count, line); - char *real_path = realpath(line, NULL); - if (starts_with(real_path, LEGAL_SUBHAL_PATH_PREFIX) || - starts_with(real_path, LEGAL_SUBHAL_ALTERNATE_PATH_PREFIX)) { - ALOGV("accepting valid path '%s'", real_path); - char* compact_line = new char[strlen(real_path) + 1]; - strcpy(compact_line, real_path); - so_paths->push_back(compact_line); - } else { - ALOGW("rejecting path '%s' because it does not start with '%s' or '%s'", - real_path, LEGAL_SUBHAL_PATH_PREFIX, LEGAL_SUBHAL_ALTERNATE_PATH_PREFIX); - } - free(real_path); + while (std::getline(conf_file, line)) { + ALOGV("config file line: '%s'", line.c_str()); + so_paths->push_back(line); } - free(line); - fclose(conf_file); - ALOGV("hals.conf contained %d lines", line_count); } /* @@ -510,15 +490,15 @@ static void lazy_init_modules() { pthread_mutex_unlock(&init_modules_mutex); return; } - std::vector<char*> *so_paths = new std::vector<char*>(); + std::vector<std::string> *so_paths = new std::vector<std::string>(); get_so_paths(so_paths); // dlopen the module files and cache their module symbols in sub_hw_modules sub_hw_modules = new std::vector<hw_module_t *>(); dlerror(); // clear any old errors const char* sym = HAL_MODULE_INFO_SYM_AS_STR; - for (std::vector<char*>::iterator it = so_paths->begin(); it != so_paths->end(); it++) { - char* path = *it; + for (std::vector<std::string>::iterator it = so_paths->begin(); it != so_paths->end(); it++) { + const char* path = it->c_str(); void* lib_handle = dlopen(path, RTLD_LAZY); if (lib_handle == NULL) { ALOGW("dlerror(): %s", dlerror()); |