summaryrefslogtreecommitdiffstats
path: root/modules
diff options
context:
space:
mode:
Diffstat (limited to 'modules')
-rw-r--r--modules/audio/Android.mk13
-rw-r--r--modules/audio/audio_amplifier.c146
-rw-r--r--modules/audio_remote_submix/audio_hw.cpp55
-rw-r--r--modules/sensors/Android.mk4
-rw-r--r--modules/sensors/multihal.cpp46
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 cd67f6d..5fedd4d 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>
@@ -36,8 +38,6 @@
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;
@@ -463,39 +463,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);
}
/*
@@ -508,15 +488,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());