diff options
author | Dima Zavin <dima@android.com> | 2011-04-20 16:38:05 -0700 |
---|---|---|
committer | Dima Zavin <dima@android.com> | 2011-04-27 14:08:57 -0700 |
commit | 8cc353abc94a557dcff0f2989f7ca6351fcfdb08 (patch) | |
tree | dc2279a2b6dbcccfb90fe96628bc9819f872641a /modules/audio | |
parent | 7e0331661814065af64cbd04b8b08e1264e8d6d9 (diff) | |
download | hardware_libhardware-8cc353abc94a557dcff0f2989f7ca6351fcfdb08.zip hardware_libhardware-8cc353abc94a557dcff0f2989f7ca6351fcfdb08.tar.gz hardware_libhardware-8cc353abc94a557dcff0f2989f7ca6351fcfdb08.tar.bz2 |
libhardware: add stub audio and audio_policy modules
Change-Id: Ib6c0c49dbc369b735b2ac5fb5b583de96c3e9f3e
Signed-off-by: Dima Zavin <dima@android.com>
Diffstat (limited to 'modules/audio')
-rw-r--r-- | modules/audio/Android.mk | 43 | ||||
-rw-r--r-- | modules/audio/audio_hw.c | 412 | ||||
-rw-r--r-- | modules/audio/audio_policy.c | 318 |
3 files changed, 773 insertions, 0 deletions
diff --git a/modules/audio/Android.mk b/modules/audio/Android.mk new file mode 100644 index 0000000..f773079 --- /dev/null +++ b/modules/audio/Android.mk @@ -0,0 +1,43 @@ +# Copyright (C) 2011 The Android 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. + +LOCAL_PATH := $(call my-dir) + +# The default audio HAL module, which is a stub, that is loaded if no other +# device specific modules are present. The exact load order can be seen in +# libhardware/hardware.c +# +# The format of the name is audio.<type>.<hardware/etc>.so where the only +# required type is 'primary'. Other possibilites are 'a2dp', 'usb', etc. +include $(CLEAR_VARS) + +LOCAL_MODULE := audio.primary.default +LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw +LOCAL_SRC_FILES := audio_hw.c +LOCAL_SHARED_LIBRARIES := liblog libcutils +LOCAL_MODULE_TAGS := optional + +include $(BUILD_SHARED_LIBRARY) + +# The stub audio policy HAL module that can be used as a skeleton for +# new implementations. +include $(CLEAR_VARS) + +LOCAL_MODULE := audio_policy.stub +LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw +LOCAL_SRC_FILES := audio_policy.c +LOCAL_SHARED_LIBRARIES := liblog libcutils +LOCAL_MODULE_TAGS := optional + +include $(BUILD_SHARED_LIBRARY) diff --git a/modules/audio/audio_hw.c b/modules/audio/audio_hw.c new file mode 100644 index 0000000..bb6659d --- /dev/null +++ b/modules/audio/audio_hw.c @@ -0,0 +1,412 @@ +/* + * Copyright (C) 2011 The Android 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 "audio_hw_default" +//#define LOG_NDEBUG 0 + +#include <errno.h> +#include <pthread.h> +#include <stdint.h> +#include <sys/time.h> + +#include <cutils/log.h> + +#include <hardware/hardware.h> +#include <hardware/audio.h> +#include <hardware/audio_hal.h> + +struct stub_audio_device { + struct audio_hw_device device; +}; + +struct stub_stream_out { + struct audio_stream_out stream; +}; + +struct stub_stream_in { + struct audio_stream_in stream; +}; + +static uint32_t out_get_sample_rate(const struct audio_stream *stream) +{ + return 44100; +} + +static int out_set_sample_rate(struct audio_stream *stream, uint32_t rate) +{ + return 0; +} + +static size_t out_get_buffer_size(const struct audio_stream *stream) +{ + return 4096; +} + +static uint32_t out_get_channels(const struct audio_stream *stream) +{ + return AUDIO_CHANNEL_OUT_STEREO; +} + +static int out_get_format(const struct audio_stream *stream) +{ + return AUDIO_FORMAT_PCM_16_BIT; +} + +static int out_set_format(struct audio_stream *stream, int format) +{ + return 0; +} + +static int out_standby(struct audio_stream *stream) +{ + return 0; +} + +static int out_dump(const struct audio_stream *stream, int fd) +{ + return 0; +} + +static int out_set_parameters(struct audio_stream *stream, const char *kvpairs) +{ + return 0; +} + +static char * out_get_parameters(const struct audio_stream *stream, const char *keys) +{ + return strdup(""); +} + +static uint32_t out_get_latency(const struct audio_stream_out *stream) +{ + return 0; +} + +static int out_set_volume(struct audio_stream_out *stream, float left, + float right) +{ + return 0; +} + +static ssize_t out_write(struct audio_stream_out *stream, const void* buffer, + size_t bytes) +{ + /* XXX: fake timing for audio output */ + usleep(bytes * 1000000 / audio_stream_frame_size(&stream->common) / + out_get_sample_rate(&stream->common)); + return bytes; +} + +static int out_get_render_position(const struct audio_stream_out *stream, + uint32_t *dsp_frames) +{ + return -EINVAL; +} + +/** audio_stream_in implementation **/ +static uint32_t in_get_sample_rate(const struct audio_stream *stream) +{ + return 8000; +} + +static int in_set_sample_rate(struct audio_stream *stream, uint32_t rate) +{ + return 0; +} + +static size_t in_get_buffer_size(const struct audio_stream *stream) +{ + return 320; +} + +static uint32_t in_get_channels(const struct audio_stream *stream) +{ + return AUDIO_CHANNEL_IN_MONO; +} + +static int in_get_format(const struct audio_stream *stream) +{ + return AUDIO_FORMAT_PCM_16_BIT; +} + +static int in_set_format(struct audio_stream *stream, int format) +{ + return 0; +} + +static int in_standby(struct audio_stream *stream) +{ + return 0; +} + +static int in_dump(const struct audio_stream *stream, int fd) +{ + return 0; +} + +static int in_set_parameters(struct audio_stream *stream, const char *kvpairs) +{ + return 0; +} + +static char * in_get_parameters(const struct audio_stream *stream, + const char *keys) +{ + return strdup(""); +} + +static int in_set_gain(struct audio_stream_in *stream, float gain) +{ + return 0; +} + +static ssize_t in_read(struct audio_stream_in *stream, void* buffer, + size_t bytes) +{ + /* XXX: fake timing for audio input */ + usleep(bytes * 1000000 / audio_stream_frame_size(&stream->common) / + in_get_sample_rate(&stream->common)); + return bytes; +} + +static uint32_t in_get_input_frames_lost(struct audio_stream_in *stream) +{ + return 0; +} + + +static int adev_open_output_stream(struct audio_hw_device *dev, + uint32_t devices, int *format, + uint32_t *channels, uint32_t *sample_rate, + struct audio_stream_out **stream_out) +{ + struct stub_audio_device *ladev = (struct stub_audio_device *)dev; + struct stub_stream_out *out; + int ret; + + out = (struct stub_stream_out *)calloc(1, sizeof(struct stub_stream_out)); + if (!out) + return -ENOMEM; + + out->stream.common.get_sample_rate = out_get_sample_rate; + out->stream.common.set_sample_rate = out_set_sample_rate; + out->stream.common.get_buffer_size = out_get_buffer_size; + out->stream.common.get_channels = out_get_channels; + out->stream.common.get_format = out_get_format; + out->stream.common.set_format = out_set_format; + out->stream.common.standby = out_standby; + out->stream.common.dump = out_dump; + out->stream.common.set_parameters = out_set_parameters; + out->stream.common.get_parameters = out_get_parameters; + out->stream.get_latency = out_get_latency; + out->stream.set_volume = out_set_volume; + out->stream.write = out_write; + out->stream.get_render_position = out_get_render_position; + + *stream_out = &out->stream; + return 0; + +err_open: + free(out); + *stream_out = NULL; + return ret; +} + +static void adev_close_output_stream(struct audio_hw_device *dev, + struct audio_stream_out *stream) +{ + free(stream); +} + +static int adev_set_parameters(struct audio_hw_device *dev, const char *kvpairs) +{ + return -ENOSYS; +} + +static char * adev_get_parameters(const struct audio_hw_device *dev, + const char *keys) +{ + return NULL; +} + +static int adev_init_check(const struct audio_hw_device *dev) +{ + return 0; +} + +static int adev_set_voice_volume(struct audio_hw_device *dev, float volume) +{ + return -ENOSYS; +} + +static int adev_set_master_volume(struct audio_hw_device *dev, float volume) +{ + return -ENOSYS; +} + +static int adev_set_mode(struct audio_hw_device *dev, int mode) +{ + return 0; +} + +static int adev_set_mic_mute(struct audio_hw_device *dev, bool state) +{ + return -ENOSYS; +} + +static int adev_get_mic_mute(const struct audio_hw_device *dev, bool *state) +{ + return -ENOSYS; +} + +static size_t adev_get_input_buffer_size(const struct audio_hw_device *dev, + uint32_t sample_rate, int format, + int channel_count) +{ + return 320; +} + +static int adev_open_input_stream(struct audio_hw_device *dev, uint32_t devices, + int *format, uint32_t *channels, + uint32_t *sample_rate, + audio_in_acoustics_t acoustics, + struct audio_stream_in **stream_in) +{ + struct stub_audio_device *ladev = (struct stub_audio_device *)dev; + struct stub_stream_in *in; + int ret; + + in = (struct stub_stream_in *)calloc(1, sizeof(struct stub_stream_in)); + if (!in) + return -ENOMEM; + + in->stream.common.get_sample_rate = in_get_sample_rate; + in->stream.common.set_sample_rate = in_set_sample_rate; + in->stream.common.get_buffer_size = in_get_buffer_size; + in->stream.common.get_channels = in_get_channels; + in->stream.common.get_format = in_get_format; + in->stream.common.set_format = in_set_format; + in->stream.common.standby = in_standby; + in->stream.common.dump = in_dump; + in->stream.common.set_parameters = in_set_parameters; + in->stream.common.get_parameters = in_get_parameters; + in->stream.set_gain = in_set_gain; + in->stream.read = in_read; + in->stream.get_input_frames_lost = in_get_input_frames_lost; + + *stream_in = &in->stream; + return 0; + +err_open: + free(in); + *stream_in = NULL; + return ret; +} + +static void adev_close_input_stream(struct audio_hw_device *dev, + struct audio_stream_in *in) +{ + return; +} + +static int adev_dump(const audio_hw_device_t *device, int fd) +{ + return 0; +} + +static int adev_close(hw_device_t *device) +{ + free(device); + return 0; +} + +static uint32_t adev_get_supported_devices(const struct audio_hw_device *dev) +{ + return (/* OUT */ + AUDIO_DEVICE_OUT_EARPIECE | + AUDIO_DEVICE_OUT_SPEAKER | + AUDIO_DEVICE_OUT_WIRED_HEADSET | + AUDIO_DEVICE_OUT_WIRED_HEADPHONE | + AUDIO_DEVICE_OUT_AUX_DIGITAL | + AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET | + AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET | + AUDIO_DEVICE_OUT_ALL_SCO | + AUDIO_DEVICE_OUT_DEFAULT | + /* IN */ + AUDIO_DEVICE_IN_COMMUNICATION | + AUDIO_DEVICE_IN_AMBIENT | + AUDIO_DEVICE_IN_BUILTIN_MIC | + AUDIO_DEVICE_IN_WIRED_HEADSET | + AUDIO_DEVICE_IN_AUX_DIGITAL | + AUDIO_DEVICE_IN_BACK_MIC | + AUDIO_DEVICE_IN_ALL_SCO | + AUDIO_DEVICE_IN_DEFAULT); +} + +static int adev_open(const hw_module_t* module, const char* name, + hw_device_t** device) +{ + struct stub_audio_device *adev; + int ret; + + if (strcmp(name, AUDIO_HARDWARE_INTERFACE) != 0) + return -EINVAL; + + adev = calloc(1, sizeof(struct stub_audio_device)); + if (!adev) + return -ENOMEM; + + adev->device.common.tag = HARDWARE_DEVICE_TAG; + adev->device.common.version = 0; + adev->device.common.module = (struct hw_module_t *) module; + adev->device.common.close = adev_close; + + adev->device.get_supported_devices = adev_get_supported_devices; + adev->device.init_check = adev_init_check; + adev->device.set_voice_volume = adev_set_voice_volume; + adev->device.set_master_volume = adev_set_master_volume; + adev->device.set_mode = adev_set_mode; + adev->device.set_mic_mute = adev_set_mic_mute; + adev->device.get_mic_mute = adev_get_mic_mute; + adev->device.set_parameters = adev_set_parameters; + adev->device.get_parameters = adev_get_parameters; + adev->device.get_input_buffer_size = adev_get_input_buffer_size; + adev->device.open_output_stream = adev_open_output_stream; + adev->device.close_output_stream = adev_close_output_stream; + adev->device.open_input_stream = adev_open_input_stream; + adev->device.close_input_stream = adev_close_input_stream; + adev->device.dump = adev_dump; + + *device = &adev->device.common; + + return 0; +} + +static struct hw_module_methods_t hal_module_methods = { + .open = adev_open, +}; + +struct audio_module HAL_MODULE_INFO_SYM = { + .common = { + .tag = HARDWARE_MODULE_TAG, + .version_major = 1, + .version_minor = 0, + .id = AUDIO_HARDWARE_MODULE_ID, + .name = "Default audio HW HAL", + .author = "The Android Open Source Project", + .methods = &hal_module_methods, + }, +}; diff --git a/modules/audio/audio_policy.c b/modules/audio/audio_policy.c new file mode 100644 index 0000000..4d5258d --- /dev/null +++ b/modules/audio/audio_policy.c @@ -0,0 +1,318 @@ +/* + * Copyright (C) 2011 The Android 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 "audio_policy_default" +//#define LOG_NDEBUG 0 + +#include <errno.h> +#include <stdint.h> +#include <stdlib.h> +#include <string.h> + +#include <hardware/hardware.h> +#include <hardware/audio.h> +#include <hardware/audio_policy.h> +#include <hardware/audio_policy_hal.h> + +struct default_ap_module { + struct audio_policy_module module; +}; + +struct default_ap_device { + struct audio_policy_device device; +}; + +struct default_audio_policy { + struct audio_policy policy; + + struct audio_policy_service_ops *aps_ops; + void *service; +}; + +static int ap_set_device_connection_state(struct audio_policy *pol, + audio_devices_t device, + audio_policy_dev_state_t state, + const char *device_address) +{ + return -ENOSYS; +} + +static audio_policy_dev_state_t ap_get_device_connection_state( + const struct audio_policy *pol, + audio_devices_t device, + const char *device_address) +{ + return AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE; +} + +static void ap_set_phone_state(struct audio_policy *pol, int state) +{ +} + +static void ap_set_ringer_mode(struct audio_policy *pol, uint32_t mode, + uint32_t mask) +{ +} + +static void ap_set_force_use(struct audio_policy *pol, + audio_policy_force_use_t usage, + audio_policy_forced_cfg_t config) +{ +} + + /* retreive current device category forced for a given usage */ +static audio_policy_forced_cfg_t ap_get_force_use( + const struct audio_policy *pol, + audio_policy_force_use_t usage) +{ + return AUDIO_POLICY_FORCE_NONE; +} + +/* if can_mute is true, then audio streams that are marked ENFORCED_AUDIBLE + * can still be muted. */ +static void ap_set_can_mute_enforced_audible(struct audio_policy *pol, + bool can_mute) +{ +} + +static int ap_init_check(const struct audio_policy *pol) +{ + return 0; +} + +static audio_io_handle_t ap_get_output(struct audio_policy *pol, + audio_stream_type_t stream, + uint32_t sampling_rate, + uint32_t format, + uint32_t channels, + audio_policy_output_flags_t flags) +{ + return 0; +} + +static int ap_start_output(struct audio_policy *pol, audio_io_handle_t output, + audio_stream_type_t stream, int session) +{ + return -ENOSYS; +} + +static int ap_stop_output(struct audio_policy *pol, audio_io_handle_t output, + audio_stream_type_t stream, int session) +{ + return -ENOSYS; +} + +static void ap_release_output(struct audio_policy *pol, + audio_io_handle_t output) +{ +} + +static audio_io_handle_t ap_get_input(struct audio_policy *pol, int inputSource, + uint32_t sampling_rate, + uint32_t format, + uint32_t channels, + audio_in_acoustics_t acoustics) +{ + return 0; +} + +static int ap_start_input(struct audio_policy *pol, audio_io_handle_t input) +{ + return -ENOSYS; +} + +static int ap_stop_input(struct audio_policy *pol, audio_io_handle_t input) +{ + return -ENOSYS; +} + +static void ap_release_input(struct audio_policy *pol, audio_io_handle_t input) +{ +} + +static void ap_init_stream_volume(struct audio_policy *pol, + audio_stream_type_t stream, int index_min, + int index_max) +{ +} + +static int ap_set_stream_volume_index(struct audio_policy *pol, + audio_stream_type_t stream, + int index) +{ + return -ENOSYS; +} + +static int ap_get_stream_volume_index(const struct audio_policy *pol, + audio_stream_type_t stream, + int *index) +{ + return -ENOSYS; +} + +static uint32_t ap_get_strategy_for_stream(const struct audio_policy *pol, + audio_stream_type_t stream) +{ + return 0; +} + +static uint32_t ap_get_devices_for_stream(const struct audio_policy *pol, + audio_stream_type_t stream) +{ + return 0; +} + +static audio_io_handle_t ap_get_output_for_effect(struct audio_policy *pol, + struct effect_descriptor_s *desc) +{ + return 0; +} + +static int ap_register_effect(struct audio_policy *pol, + struct effect_descriptor_s *desc, + audio_io_handle_t output, + uint32_t strategy, + int session, + int id) +{ + return -ENOSYS; +} + +static int ap_unregister_effect(struct audio_policy *pol, int id) +{ + return -ENOSYS; +} + +static bool ap_is_stream_active(const struct audio_policy *pol, int stream, + uint32_t in_past_ms) +{ + return false; +} + +static int ap_dump(const struct audio_policy *pol, int fd) +{ + return -ENOSYS; +} + +static int create_default_ap(const struct audio_policy_device *device, + struct audio_policy_service_ops *aps_ops, + void *service, + struct audio_policy **ap) +{ + struct default_ap_device *dev; + struct default_audio_policy *dap; + int ret; + + *ap = NULL; + + if (!service || !aps_ops) + return -EINVAL; + + dap = (struct default_audio_policy *)calloc(1, sizeof(*dap)); + if (!dap) + return -ENOMEM; + + dap->policy.set_device_connection_state = ap_set_device_connection_state; + dap->policy.get_device_connection_state = ap_get_device_connection_state; + dap->policy.set_phone_state = ap_set_phone_state; + dap->policy.set_ringer_mode = ap_set_ringer_mode; + dap->policy.set_force_use = ap_set_force_use; + dap->policy.get_force_use = ap_get_force_use; + dap->policy.set_can_mute_enforced_audible = + ap_set_can_mute_enforced_audible; + dap->policy.init_check = ap_init_check; + dap->policy.get_output = ap_get_output; + dap->policy.start_output = ap_start_output; + dap->policy.stop_output = ap_stop_output; + dap->policy.release_output = ap_release_output; + dap->policy.get_input = ap_get_input; + dap->policy.start_input = ap_start_input; + dap->policy.stop_input = ap_stop_input; + dap->policy.release_input = ap_release_input; + dap->policy.init_stream_volume = ap_init_stream_volume; + dap->policy.set_stream_volume_index = ap_set_stream_volume_index; + dap->policy.get_stream_volume_index = ap_get_stream_volume_index; + dap->policy.get_strategy_for_stream = ap_get_strategy_for_stream; + dap->policy.get_devices_for_stream = ap_get_devices_for_stream; + dap->policy.get_output_for_effect = ap_get_output_for_effect; + dap->policy.register_effect = ap_register_effect; + dap->policy.unregister_effect = ap_unregister_effect; + dap->policy.is_stream_active = ap_is_stream_active; + dap->policy.dump = ap_dump; + + dap->service = service; + dap->aps_ops = aps_ops; + + *ap = &dap->policy; + return 0; +} + +static int destroy_default_ap(const struct audio_policy_device *ap_dev, + struct audio_policy *ap) +{ + free(ap); + return 0; +} + +static int default_ap_dev_close(hw_device_t* device) +{ + free(device); + return 0; +} + +static int default_ap_dev_open(const hw_module_t* module, const char* name, + hw_device_t** device) +{ + struct default_ap_device *dev; + + *device = NULL; + + if (strcmp(name, AUDIO_POLICY_INTERFACE) != 0) + return -EINVAL; + + dev = (struct default_ap_device *)calloc(1, sizeof(*dev)); + if (!dev) + return -ENOMEM; + + dev->device.common.tag = HARDWARE_DEVICE_TAG; + dev->device.common.version = 0; + dev->device.common.module = (hw_module_t *)module; + dev->device.common.close = default_ap_dev_close; + dev->device.create_audio_policy = create_default_ap; + dev->device.destroy_audio_policy = destroy_default_ap; + + *device = &dev->device.common; + + return 0; +} + +static struct hw_module_methods_t default_ap_module_methods = { + .open = default_ap_dev_open, +}; + +struct default_ap_module HAL_MODULE_INFO_SYM = { + .module = { + .common = { + .tag = HARDWARE_MODULE_TAG, + .version_major = 1, + .version_minor = 0, + .id = AUDIO_POLICY_HARDWARE_MODULE_ID, + .name = "Default audio policy HAL", + .author = "The Android Open Source Project", + .methods = &default_ap_module_methods, + }, + }, +}; |