Merge "Define SENSOR_TYPE_PICK_UP_GESTURE." into lmp-dev
diff --git a/include/hardware/audio.h b/include/hardware/audio.h
index 7ff5b78..95111dd 100644
--- a/include/hardware/audio.h
+++ b/include/hardware/audio.h
@@ -579,7 +579,8 @@
audio_io_handle_t handle,
audio_devices_t devices,
struct audio_config *config,
- struct audio_stream_in **stream_in);
+ struct audio_stream_in **stream_in,
+ audio_input_flags_t flags);
void (*close_input_stream)(struct audio_hw_device *dev,
struct audio_stream_in *stream_in);
diff --git a/include/hardware/hwcomposer.h b/include/hardware/hwcomposer.h
index f647ab3..882bade 100644
--- a/include/hardware/hwcomposer.h
+++ b/include/hardware/hwcomposer.h
@@ -678,16 +678,24 @@
* total number of configurations available for the display is returned in
* *numConfigs. If *numConfigs is zero on entry, then configs may be NULL.
*
- * HWC_DEVICE_API_VERSION_1_1 does not provide a way to choose a config.
- * For displays that support multiple configurations, the h/w composer
- * implementation should choose one and report it as the first config in
- * the list. Reporting the not-chosen configs is not required.
+ * Hardware composers implementing HWC_DEVICE_API_VERSION_1_3 or prior
+ * shall choose one configuration to activate and report it as the first
+ * entry in the returned list. Reporting the inactive configurations is not
+ * required.
*
- * Returns 0 on success or -errno on error. If disp is a hotpluggable
- * display type and no display is connected, an error should be returned.
+ * HWC_DEVICE_API_VERSION_1_4 and later provide configuration management
+ * through SurfaceFlinger, and hardware composers implementing these APIs
+ * must also provide getActiveConfig and setActiveConfig. Hardware composers
+ * implementing these API versions may choose not to activate any
+ * configuration, leaving configuration selection to higher levels of the
+ * framework.
+ *
+ * Returns 0 on success or a negative error code on error. If disp is a
+ * hotpluggable display type and no display is connected, an error shall be
+ * returned.
*
* This field is REQUIRED for HWC_DEVICE_API_VERSION_1_1 and later.
- * It should be NULL for previous versions.
+ * It shall be NULL for previous versions.
*/
int (*getDisplayConfigs)(struct hwc_composer_device_1* dev, int disp,
uint32_t* configs, size_t* numConfigs);
@@ -704,19 +712,54 @@
* array will have one less value than the attributes array.
*
* This field is REQUIRED for HWC_DEVICE_API_VERSION_1_1 and later.
- * It should be NULL for previous versions.
+ * It shall be NULL for previous versions.
*
* If disp is a hotpluggable display type and no display is connected,
* or if config is not a valid configuration for the display, a negative
- * value should be returned.
+ * error code shall be returned.
*/
int (*getDisplayAttributes)(struct hwc_composer_device_1* dev, int disp,
uint32_t config, const uint32_t* attributes, int32_t* values);
/*
+ * (*getActiveConfig)() returns the index of the configuration that is
+ * currently active on the connected display. The index is relative to
+ * the list of configuration handles returned by getDisplayConfigs. If there
+ * is no active configuration, -1 shall be returned.
+ *
+ * Returns the configuration index on success or -1 on error.
+ *
+ * This field is REQUIRED for HWC_DEVICE_API_VERSION_1_4 and later.
+ * It shall be NULL for previous versions.
+ */
+ int (*getActiveConfig)(struct hwc_composer_device_1* dev, int disp);
+
+ /*
+ * (*setActiveConfig)() instructs the hardware composer to switch to the
+ * display configuration at the given index in the list of configuration
+ * handles returned by getDisplayConfigs.
+ *
+ * If this function returns without error, any subsequent calls to
+ * getActiveConfig shall return the index set by this function until one
+ * of the following occurs:
+ * 1) Another successful call of this function
+ * 2) The display is disconnected
+ *
+ * Returns 0 on success or a negative error code on error. If disp is a
+ * hotpluggable display type and no display is connected, or if index is
+ * outside of the range of hardware configurations returned by
+ * getDisplayConfigs, an error shall be returned.
+ *
+ * This field is REQUIRED for HWC_DEVICE_API_VERSION_1_4 and later.
+ * It shall be NULL for previous versions.
+ */
+ int (*setActiveConfig)(struct hwc_composer_device_1* dev, int disp,
+ int index);
+
+ /*
* Reserved for future use. Must be NULL.
*/
- void* reserved_proc[4];
+ void* reserved_proc[2];
} hwc_composer_device_1_t;
diff --git a/modules/audio/audio_hw.c b/modules/audio/audio_hw.c
index 2f44d95..ef070c1 100644
--- a/modules/audio/audio_hw.c
+++ b/modules/audio/audio_hw.c
@@ -327,7 +327,8 @@
audio_io_handle_t handle,
audio_devices_t devices,
struct audio_config *config,
- struct audio_stream_in **stream_in)
+ struct audio_stream_in **stream_in,
+ audio_input_flags_t flags __unused)
{
struct stub_audio_device *ladev = (struct stub_audio_device *)dev;
struct stub_stream_in *in;
diff --git a/modules/audio_remote_submix/audio_hw.cpp b/modules/audio_remote_submix/audio_hw.cpp
index c7e4305..9e824b1 100644
--- a/modules/audio_remote_submix/audio_hw.cpp
+++ b/modules/audio_remote_submix/audio_hw.cpp
@@ -1373,7 +1373,8 @@
audio_io_handle_t handle,
audio_devices_t devices,
struct audio_config *config,
- struct audio_stream_in **stream_in)
+ struct audio_stream_in **stream_in,
+ audio_input_flags_t flags __unused)
{
struct submix_audio_device *rsxadev = audio_hw_device_get_submix_audio_device(dev);
struct submix_stream_in *in;
diff --git a/modules/consumerir/consumerir.c b/modules/consumerir/consumerir.c
index 83eba75..87039cc 100644
--- a/modules/consumerir/consumerir.c
+++ b/modules/consumerir/consumerir.c
@@ -32,8 +32,8 @@
{.min = 56000, .max = 56000},
};
-static int consumerir_transmit(struct consumerir_device *dev,
- int carrier_freq, int pattern[], int pattern_len)
+static int consumerir_transmit(struct consumerir_device *dev __unused,
+ int carrier_freq, const int pattern[], int pattern_len)
{
int total_time = 0;
long i;
@@ -48,12 +48,12 @@
return 0;
}
-static int consumerir_get_num_carrier_freqs(struct consumerir_device *dev)
+static int consumerir_get_num_carrier_freqs(struct consumerir_device *dev __unused)
{
return ARRAY_SIZE(consumerir_freqs);
}
-static int consumerir_get_carrier_freqs(struct consumerir_device *dev,
+static int consumerir_get_carrier_freqs(struct consumerir_device *dev __unused,
size_t len, consumerir_freq_range_t *ranges)
{
size_t to_copy = ARRAY_SIZE(consumerir_freqs);
diff --git a/modules/usbaudio/audio_hw.c b/modules/usbaudio/audio_hw.c
index 2085268..8fbd528 100644
--- a/modules/usbaudio/audio_hw.c
+++ b/modules/usbaudio/audio_hw.c
@@ -16,6 +16,7 @@
#define LOG_TAG "usb_audio_hw"
/*#define LOG_NDEBUG 0*/
+/*#define LOG_PCM_PARAMS 0*/
#include <errno.h>
#include <inttypes.h>
@@ -36,6 +37,8 @@
#include <tinyalsa/asoundlib.h>
+#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
+
/* This is the default configuration to hand to The Framework on the initial
* adev_open_output_stream(). Actual device attributes will be used on the subsequent
* adev_open_output_stream() after the card and device number have been set in out_set_parameters()
@@ -69,18 +72,22 @@
.stop_threshold = (IN_PERIOD_SIZE * IN_PERIOD_COUNT),
};
+struct audio_device_profile {
+ int card;
+ int device;
+ int direction; /* PCM_OUT or PCM_IN */
+};
+
struct audio_device {
struct audio_hw_device hw_device;
pthread_mutex_t lock; /* see note below on mutex acquisition order */
/* output */
- int out_card;
- int out_device;
+ struct audio_device_profile out_profile;
/* input */
- int in_card;
- int in_device;
+ struct audio_device_profile in_profile;
bool standby;
};
@@ -93,6 +100,7 @@
bool standby;
struct audio_device *dev; /* hardware information */
+ struct audio_device_profile * profile;
void * conversion_buffer; /* any conversions are put into here
* they could come from here too if
@@ -116,6 +124,8 @@
struct audio_device *dev;
+ struct audio_device_profile * profile;
+
struct audio_config hal_pcm_config;
/* this is the format the framework thinks it's using. We may need to convert from the actual
@@ -221,7 +231,7 @@
* in_buff_channels Specifies the number of channels in the input buffer.
* out_buff points to the buffer to receive converted PCM16 samples.
* out_buff_channels Specifies the number of channels in the output buffer.
- * num_in_samples size of input buffer in SAMPLES
+ * num_in_bytes size of input buffer in BYTES
* returns
* the number of BYTES of output data.
* NOTE
@@ -231,16 +241,18 @@
* support 4-channel devices.
* TODO Move this to a utilities module.
*/
-static size_t expand_channels_16(const short* in_buff, int in_buff_chans,
- short* out_buff, int out_buff_chans,
- size_t num_in_samples)
+static size_t expand_channels_16(const int16_t* in_buff, int in_buff_chans,
+ int16_t* out_buff, int out_buff_chans,
+ size_t num_in_bytes)
{
/*
* Move from back to front so that the conversion can be done in-place
* i.e. in_buff == out_buff
* NOTE: num_in_samples * out_buff_channels must be an even multiple of in_buff_chans
*/
- int num_out_samples = (num_in_samples * out_buff_chans)/in_buff_chans;
+ size_t num_in_samples = num_in_bytes / sizeof(int16_t);
+
+ size_t num_out_samples = (num_in_samples * out_buff_chans) / in_buff_chans;
short* dst_ptr = out_buff + num_out_samples - 1;
size_t src_index;
@@ -257,7 +269,7 @@
}
/* return number of *bytes* generated */
- return num_out_samples * sizeof(short);
+ return num_out_samples * sizeof(int16_t);
}
/*
@@ -267,7 +279,7 @@
* in_buff_channels Specifies the number of channels in the input buffer.
* out_buff points to the buffer to receive converted PCM16 samples.
* out_buff_channels Specifies the number of channels in the output buffer.
- * num_in_samples size of input buffer in SAMPLES
+ * num_in_bytes size of input buffer in BYTES
* returns
* the number of BYTES of output data.
* NOTE
@@ -277,24 +289,26 @@
* support 4-channel devices.
* TODO Move this to a utilities module.
*/
-static size_t contract_channels_16(short* in_buff, int in_buff_chans,
- short* out_buff, int out_buff_chans,
- size_t num_in_samples)
+static size_t contract_channels_16(const int16_t* in_buff, size_t in_buff_chans,
+ int16_t* out_buff, size_t out_buff_chans,
+ size_t num_in_bytes)
{
/*
* Move from front to back so that the conversion can be done in-place
* i.e. in_buff == out_buff
* NOTE: num_in_samples * out_buff_channels must be an even multiple of in_buff_chans
*/
- int num_out_samples = (num_in_samples * out_buff_chans)/in_buff_chans;
+ size_t num_in_samples = num_in_bytes / sizeof(int16_t);
- int num_skip_samples = in_buff_chans - out_buff_chans;
+ size_t num_out_samples = (num_in_samples * out_buff_chans) / in_buff_chans;
- short* dst_ptr = out_buff;
- short* src_ptr = in_buff;
+ size_t num_skip_samples = in_buff_chans - out_buff_chans;
+
+ int16_t* dst_ptr = out_buff;
+ const int16_t* src_ptr = in_buff;
size_t src_index;
for (src_index = 0; src_index < num_in_samples; src_index += in_buff_chans) {
- int dst_offset;
+ size_t dst_offset;
for (dst_offset = 0; dst_offset < out_buff_chans; dst_offset++) {
*dst_ptr++ = *src_ptr++;
}
@@ -302,7 +316,169 @@
}
/* return number of *bytes* generated */
- return num_out_samples * sizeof(short);
+ return num_out_samples * sizeof(int16_t);
+}
+
+/*
+ * Convert a buffer of N-channel, interleaved PCM32 samples to M-channel PCM32 channels
+ * (where N < M).
+ * in_buff points to the buffer of PCM32 samples
+ * in_buff_channels Specifies the number of channels in the input buffer.
+ * out_buff points to the buffer to receive converted PCM32 samples.
+ * out_buff_channels Specifies the number of channels in the output buffer.
+ * num_in_bytes size of input buffer in BYTES
+ * returns
+ * the number of BYTES of output data.
+ * NOTE
+ * channels > N are filled with silence.
+ * This conversion is safe to do in-place (in_buff == out_buff)
+ * We are doing this since we *always* present to The Framework as STEREO device, but need to
+ * support 4-channel devices.
+ * TODO Move this to a utilities module.
+ */
+static size_t expand_channels_32(const int32_t* in_buff, size_t in_buff_chans,
+ int32_t* out_buff, size_t out_buff_chans,
+ size_t num_in_bytes)
+{
+ /*
+ * Move from back to front so that the conversion can be done in-place
+ * i.e. in_buff == out_buff
+ * NOTE: num_in_samples * out_buff_channels must be an even multiple of in_buff_chans
+ */
+ size_t num_in_samples = num_in_bytes / sizeof(int32_t);
+
+ size_t num_out_samples = (num_in_samples * out_buff_chans) / in_buff_chans;
+
+ int32_t* dst_ptr = out_buff + num_out_samples - 1;
+ const int32_t* src_ptr = in_buff + num_in_samples - 1;
+ size_t num_zero_chans = out_buff_chans - in_buff_chans;
+ size_t src_index;
+ for (src_index = 0; src_index < num_in_samples; src_index += in_buff_chans) {
+ size_t dst_offset;
+ for (dst_offset = 0; dst_offset < num_zero_chans; dst_offset++) {
+ *dst_ptr-- = 0;
+ }
+ for (; dst_offset < out_buff_chans; dst_offset++) {
+ *dst_ptr-- = *src_ptr--;
+ }
+ }
+
+ /* return number of *bytes* generated */
+ return num_out_samples * sizeof(int32_t);
+}
+
+/*
+ * Convert a buffer of N-channel, interleaved PCM32 samples to M-channel PCM16 channels
+ * (where N > M).
+ * in_buff points to the buffer of PCM32 samples
+ * in_buff_channels Specifies the number of channels in the input buffer.
+ * out_buff points to the buffer to receive converted PCM16 samples.
+ * out_buff_channels Specifies the number of channels in the output buffer.
+ * num_in_bytes size of input buffer in BYTES
+ * returns
+ * the number of BYTES of output data.
+ * NOTE
+ * channels > N are thrown away.
+ * This conversion is safe to do in-place (in_buff == out_buff)
+ * We are doing this since we *always* present to The Framework as STEREO device, but need to
+ * support 4-channel devices.
+ * TODO Move this to a utilities module.
+ */
+static size_t contract_channels_32(const int32_t* in_buff, size_t in_buff_chans,
+ int32_t* out_buff, size_t out_buff_chans,
+ size_t num_in_bytes)
+{
+ /*
+ * Move from front to back so that the conversion can be done in-place
+ * i.e. in_buff == out_buff
+ * NOTE: num_in_samples * out_buff_channels must be an even multiple of in_buff_chans
+ */
+ size_t num_in_samples = num_in_bytes / sizeof(int32_t);
+
+ size_t num_out_samples = (num_in_samples * out_buff_chans) / in_buff_chans;
+
+ size_t num_skip_samples = in_buff_chans - out_buff_chans;
+
+ int32_t* dst_ptr = out_buff;
+ const int32_t* src_ptr = in_buff;
+ size_t src_index;
+ for (src_index = 0; src_index < num_in_samples; src_index += in_buff_chans) {
+ size_t dst_offset;
+ for (dst_offset = 0; dst_offset < out_buff_chans; dst_offset++) {
+ *dst_ptr++ = *src_ptr++;
+ }
+ src_ptr += num_skip_samples;
+ }
+
+ /* return number of *bytes* generated */
+ return num_out_samples * sizeof(int32_t);
+}
+
+static size_t contract_channels(const void* in_buff, size_t in_buff_chans,
+ void* out_buff, size_t out_buff_chans,
+ unsigned sample_size_in_bytes, size_t num_in_bytes)
+{
+ switch (sample_size_in_bytes) {
+ case 2:
+ return contract_channels_16((const int16_t*)in_buff, in_buff_chans,
+ (int16_t*)out_buff, out_buff_chans,
+ num_in_bytes);
+
+ /* TODO - do this conversion when we have a device to test it with */
+ case 3:
+ ALOGE("24-bit channel contraction not supported.");
+ return 0;
+
+ case 4:
+ return contract_channels_32((const int32_t*)in_buff, in_buff_chans,
+ (int32_t*)out_buff, out_buff_chans,
+ num_in_bytes);
+
+ default:
+ return 0;
+ }
+}
+
+static size_t expand_channels(const void* in_buff, size_t in_buff_chans,
+ void* out_buff, size_t out_buff_chans,
+ unsigned sample_size_in_bytes, size_t num_in_bytes)
+{
+ switch (sample_size_in_bytes) {
+ case 2:
+ return expand_channels_16((const int16_t*)in_buff, in_buff_chans,
+ (int16_t*)out_buff, out_buff_chans,
+ num_in_bytes);
+
+ /* TODO - do this conversion when we have a device to test it with */
+ case 3:
+ ALOGE("24-bit channel expansion not supported.");
+ return 0;
+
+ case 4:
+ return expand_channels_32((const int32_t*)in_buff, in_buff_chans,
+ (int32_t*)out_buff, out_buff_chans,
+ num_in_bytes);
+
+ default:
+ return 0;
+ }
+}
+
+static size_t adjust_channels(const void* in_buff, size_t in_buff_chans,
+ void* out_buff, size_t out_buff_chans,
+ unsigned sample_size_in_bytes, size_t num_in_bytes)
+{
+ if (out_buff_chans > in_buff_chans) {
+ return expand_channels(in_buff, in_buff_chans, out_buff, out_buff_chans,
+ sample_size_in_bytes, num_in_bytes);
+ } else if (out_buff_chans < in_buff_chans) {
+ return contract_channels(in_buff, in_buff_chans, out_buff, out_buff_chans,
+ sample_size_in_bytes, num_in_bytes);
+ } else if (in_buff != out_buff) {
+ memcpy(out_buff, in_buff, num_in_bytes);
+ }
+
+ return num_in_bytes;
}
/*
@@ -467,7 +643,7 @@
return (mask->bits[0] & 0x0004) != 0;
}
-static int get_format_for_mask(struct pcm_mask* mask)
+static audio_format_t get_format_for_mask(struct pcm_mask* mask)
{
int num_slots = sizeof(mask->bits)/ sizeof(mask->bits[0]);
int bits_per_slot = sizeof(mask->bits[0]) * 8;
@@ -495,87 +671,140 @@
}
/*
- * Maps from bit position in pcm_mask to AUDIO_ format constants.
+ * Maps from bit position in pcm_mask to PCM_ format constants.
*/
-static int const pcm_format_value_map[] = {
+static int8_t const pcm_format_value_map[] = {
PCM_FORMAT_S8, /* 00 - SNDRV_PCM_FORMAT_S8 */
- 0, /* 01 - SNDRV_PCM_FORMAT_U8 */
+ PCM_FORMAT_INVALID, /* 01 - SNDRV_PCM_FORMAT_U8 */
PCM_FORMAT_S16_LE, /* 02 - SNDRV_PCM_FORMAT_S16_LE */
- 0, /* 03 - SNDRV_PCM_FORMAT_S16_BE */
- 0, /* 04 - SNDRV_PCM_FORMAT_U16_LE */
- 0, /* 05 - SNDRV_PCM_FORMAT_U16_BE */
+ PCM_FORMAT_INVALID, /* 03 - SNDRV_PCM_FORMAT_S16_BE */
+ PCM_FORMAT_INVALID, /* 04 - SNDRV_PCM_FORMAT_U16_LE */
+ PCM_FORMAT_INVALID, /* 05 - SNDRV_PCM_FORMAT_U16_BE */
PCM_FORMAT_S24_3LE, /* 06 - SNDRV_PCM_FORMAT_S24_LE */
- 0, /* 07 - SNDRV_PCM_FORMAT_S24_BE */
- 0, /* 08 - SNDRV_PCM_FORMAT_U24_LE */
- 0, /* 09 - SNDRV_PCM_FORMAT_U24_BE */
+ PCM_FORMAT_INVALID, /* 07 - SNDRV_PCM_FORMAT_S24_BE */
+ PCM_FORMAT_INVALID, /* 08 - SNDRV_PCM_FORMAT_U24_LE */
+ PCM_FORMAT_INVALID, /* 09 - SNDRV_PCM_FORMAT_U24_BE */
PCM_FORMAT_S32_LE, /* 10 - SNDRV_PCM_FORMAT_S32_LE */
- 0, /* 11 - SNDRV_PCM_FORMAT_S32_BE */
- 0, /* 12 - SNDRV_PCM_FORMAT_U32_LE */
- 0, /* 13 - SNDRV_PCM_FORMAT_U32_BE */
- 0, /* 14 - SNDRV_PCM_FORMAT_FLOAT_LE */
- 0, /* 15 - SNDRV_PCM_FORMAT_FLOAT_BE */
- 0, /* 16 - SNDRV_PCM_FORMAT_FLOAT64_LE */
- 0, /* 17 - SNDRV_PCM_FORMAT_FLOAT64_BE */
- 0, /* 18 - SNDRV_PCM_FORMAT_IEC958_SUBFRAME_LE */
- 0, /* 19 - SNDRV_PCM_FORMAT_IEC958_SUBFRAME_BE */
- 0, /* 20 - SNDRV_PCM_FORMAT_MU_LAW */
- 0, /* 21 - SNDRV_PCM_FORMAT_A_LAW */
- 0, /* 22 - SNDRV_PCM_FORMAT_IMA_ADPCM */
- 0, /* 23 - SNDRV_PCM_FORMAT_MPEG */
- 0, /* 24 - SNDRV_PCM_FORMAT_GSM */
- 0, /* 25 -> 30 (not assigned) */
- 0,
- 0,
- 0,
- 0,
- 0,
- 0, /* 31 - SNDRV_PCM_FORMAT_SPECIAL */
+ PCM_FORMAT_INVALID, /* 11 - SNDRV_PCM_FORMAT_S32_BE */
+ PCM_FORMAT_INVALID, /* 12 - SNDRV_PCM_FORMAT_U32_LE */
+ PCM_FORMAT_INVALID, /* 13 - SNDRV_PCM_FORMAT_U32_BE */
+ PCM_FORMAT_INVALID, /* 14 - SNDRV_PCM_FORMAT_FLOAT_LE */
+ PCM_FORMAT_INVALID, /* 15 - SNDRV_PCM_FORMAT_FLOAT_BE */
+ PCM_FORMAT_INVALID, /* 16 - SNDRV_PCM_FORMAT_FLOAT64_LE */
+ PCM_FORMAT_INVALID, /* 17 - SNDRV_PCM_FORMAT_FLOAT64_BE */
+ PCM_FORMAT_INVALID, /* 18 - SNDRV_PCM_FORMAT_IEC958_SUBFRAME_LE */
+ PCM_FORMAT_INVALID, /* 19 - SNDRV_PCM_FORMAT_IEC958_SUBFRAME_BE */
+ PCM_FORMAT_INVALID, /* 20 - SNDRV_PCM_FORMAT_MU_LAW */
+ PCM_FORMAT_INVALID, /* 21 - SNDRV_PCM_FORMAT_A_LAW */
+ PCM_FORMAT_INVALID, /* 22 - SNDRV_PCM_FORMAT_IMA_ADPCM */
+ PCM_FORMAT_INVALID, /* 23 - SNDRV_PCM_FORMAT_MPEG */
+ PCM_FORMAT_INVALID, /* 24 - SNDRV_PCM_FORMAT_GSM */
+ PCM_FORMAT_INVALID, /* 25 -> 30 (not assigned) */
+ PCM_FORMAT_INVALID,
+ PCM_FORMAT_INVALID,
+ PCM_FORMAT_INVALID,
+ PCM_FORMAT_INVALID,
+ PCM_FORMAT_INVALID,
+ PCM_FORMAT_INVALID, /* 31 - SNDRV_PCM_FORMAT_SPECIAL */
PCM_FORMAT_S24_3LE, /* 32 - SNDRV_PCM_FORMAT_S24_3LE */ /* ??? */
- 0, /* 33 - SNDRV_PCM_FORMAT_S24_3BE */
- 0, /* 34 - SNDRV_PCM_FORMAT_U24_3LE */
- 0, /* 35 - SNDRV_PCM_FORMAT_U24_3BE */
- 0, /* 36 - SNDRV_PCM_FORMAT_S20_3LE */
- 0, /* 37 - SNDRV_PCM_FORMAT_S20_3BE */
- 0, /* 38 - SNDRV_PCM_FORMAT_U20_3LE */
- 0, /* 39 - SNDRV_PCM_FORMAT_U20_3BE */
- 0, /* 40 - SNDRV_PCM_FORMAT_S18_3LE */
- 0, /* 41 - SNDRV_PCM_FORMAT_S18_3BE */
- 0, /* 42 - SNDRV_PCM_FORMAT_U18_3LE */
- 0, /* 43 - SNDRV_PCM_FORMAT_U18_3BE */
- 0, /* 44 - SNDRV_PCM_FORMAT_G723_24 */
- 0, /* 45 - SNDRV_PCM_FORMAT_G723_24_1B */
- 0, /* 46 - SNDRV_PCM_FORMAT_G723_40 */
- 0, /* 47 - SNDRV_PCM_FORMAT_G723_40_1B */
- 0, /* 48 - SNDRV_PCM_FORMAT_DSD_U8 */
- 0 /* 49 - SNDRV_PCM_FORMAT_DSD_U16_LE */
+ PCM_FORMAT_INVALID, /* 33 - SNDRV_PCM_FORMAT_S24_3BE */
+ PCM_FORMAT_INVALID, /* 34 - SNDRV_PCM_FORMAT_U24_3LE */
+ PCM_FORMAT_INVALID, /* 35 - SNDRV_PCM_FORMAT_U24_3BE */
+ PCM_FORMAT_INVALID, /* 36 - SNDRV_PCM_FORMAT_S20_3LE */
+ PCM_FORMAT_INVALID, /* 37 - SNDRV_PCM_FORMAT_S20_3BE */
+ PCM_FORMAT_INVALID, /* 38 - SNDRV_PCM_FORMAT_U20_3LE */
+ PCM_FORMAT_INVALID, /* 39 - SNDRV_PCM_FORMAT_U20_3BE */
+ PCM_FORMAT_INVALID, /* 40 - SNDRV_PCM_FORMAT_S18_3LE */
+ PCM_FORMAT_INVALID, /* 41 - SNDRV_PCM_FORMAT_S18_3BE */
+ PCM_FORMAT_INVALID, /* 42 - SNDRV_PCM_FORMAT_U18_3LE */
+ PCM_FORMAT_INVALID, /* 43 - SNDRV_PCM_FORMAT_U18_3BE */
+ PCM_FORMAT_INVALID, /* 44 - SNDRV_PCM_FORMAT_G723_24 */
+ PCM_FORMAT_INVALID, /* 45 - SNDRV_PCM_FORMAT_G723_24_1B */
+ PCM_FORMAT_INVALID, /* 46 - SNDRV_PCM_FORMAT_G723_40 */
+ PCM_FORMAT_INVALID, /* 47 - SNDRV_PCM_FORMAT_G723_40_1B */
+ PCM_FORMAT_INVALID, /* 48 - SNDRV_PCM_FORMAT_DSD_U8 */
+ PCM_FORMAT_INVALID /* 49 - SNDRV_PCM_FORMAT_DSD_U16_LE */
};
+/*
+ * Scans the provided format mask and returns the first non-8 bit sample
+ * format supported by the devices.
+ */
static int get_pcm_format_for_mask(struct pcm_mask* mask) {
int num_slots = sizeof(mask->bits)/ sizeof(mask->bits[0]);
int bits_per_slot = sizeof(mask->bits[0]) * 8;
- int table_size = sizeof(pcm_format_value_map) / sizeof(pcm_format_value_map[0]);
+ int table_size = ARRAY_SIZE(pcm_format_value_map);
int slot_index, bit_index, table_index;
table_index = 0;
int num_written = 0;
- for (slot_index = 0; slot_index < num_slots; slot_index++) {
+ for (slot_index = 0; slot_index < num_slots && table_index < table_size; slot_index++) {
unsigned bit_mask = 1;
- for (bit_index = 0; bit_index < bits_per_slot; bit_index++) {
+ for (bit_index = 0; bit_index < bits_per_slot && table_index < table_size; bit_index++) {
if ((mask->bits[slot_index] & bit_mask) != 0) {
- /* just return the first one */
- return table_index < table_size
- ? pcm_format_value_map[table_index]
- : AUDIO_FORMAT_INVALID;
+ /* TODO - we don't want a low-level function to be making this decision */
+ if (table_index != 0) { /* Don't pick 8-bit */
+ /* just return the first one */
+ return (int)pcm_format_value_map[table_index];
+ }
}
bit_mask <<= 1;
table_index++;
}
}
- return 0; // is this right?
+ return PCM_FORMAT_INVALID;
}
+static bool test_out_sample_rate(struct audio_device_profile* dev_profile, unsigned rate) {
+ struct pcm_config local_config = cached_output_hardware_config;
+ local_config.rate = rate;
+
+ bool works = false; /* let's be pessimistic */
+ struct pcm * pcm =
+ pcm_open(dev_profile->card, dev_profile->device, dev_profile->direction, &local_config);
+
+ if (pcm != NULL) {
+ works = pcm_is_ready(pcm);
+ pcm_close(pcm);
+ }
+
+ return works;
+}
+
+/* sort these highest -> lowest */
+static const unsigned std_sample_rates[] =
+ {48000, 44100, 32000, 24000, 22050, 16000, 12000, 11025, 8000};
+
+static char* enum_std_sample_rates(struct audio_device_profile* dev_profile,
+ unsigned min, unsigned max)
+{
+ char buffer[128];
+ buffer[0] = '\0';
+ int buffSize = ARRAY_SIZE(buffer);
+
+ char numBuffer[32];
+
+ int numEntries = 0;
+ unsigned index;
+ for(index = 0; index < ARRAY_SIZE(std_sample_rates); index++) {
+ if (std_sample_rates[index] >= min && std_sample_rates[index] <= max &&
+ test_out_sample_rate(dev_profile, std_sample_rates[index])) {
+ if (numEntries++ != 0) {
+ strncat(buffer, "|", buffSize);
+ }
+ snprintf(numBuffer, sizeof(numBuffer), "%u", std_sample_rates[index]);
+ strncat(buffer, numBuffer, buffSize);
+ }
+ }
+
+ return strdup(buffer);
+}
+
+/*
+ * Logging
+ */
static void log_pcm_mask(const char* mask_name, struct pcm_mask* mask) {
char buff[512];
char bit_buff[32];
@@ -665,23 +894,30 @@
/*
* Reads and decodes configuration info from the specified ALSA card/device
*/
-static int read_alsa_device_config(int card, int device, int io_type, struct pcm_config * config)
+static int read_alsa_device_config(struct audio_device_profile * dev_profile,
+ struct pcm_config * config)
{
- ALOGV("usb:audio_hw - read_alsa_device_config(c:%d d:%d t:0x%X)",card, device, io_type);
+ ALOGV("usb:audio_hw - read_alsa_device_config(c:%d d:%d t:0x%X)",
+ dev_profile->card, dev_profile->device, dev_profile->direction);
- if (card < 0 || device < 0) {
+ if (dev_profile->card < 0 || dev_profile->device < 0) {
return -EINVAL;
}
- struct pcm_params * alsa_hw_params = pcm_params_get(card, device, io_type);
+ struct pcm_params * alsa_hw_params =
+ pcm_params_get(dev_profile->card, dev_profile->device, dev_profile->direction);
if (alsa_hw_params == NULL) {
return -EINVAL;
}
+ int ret = 0;
+
/*
* This Logging will be useful when testing new USB devices.
*/
- /* log_pcm_params(alsa_hw_params); */
+#ifdef LOG_PCM_PARAMS
+ log_pcm_params(alsa_hw_params);
+#endif
config->channels = pcm_params_get_min(alsa_hw_params, PCM_PARAM_CHANNELS);
config->rate = pcm_params_get_min(alsa_hw_params, PCM_PARAM_RATE);
@@ -695,8 +931,15 @@
}
config->period_count = pcm_params_get_min(alsa_hw_params, PCM_PARAM_PERIODS);
- config->format = get_pcm_format_for_mask(pcm_params_get_mask(alsa_hw_params, PCM_PARAM_FORMAT));
- return 0;
+ int format = get_pcm_format_for_mask(pcm_params_get_mask(alsa_hw_params, PCM_PARAM_FORMAT));
+ if (format == PCM_FORMAT_INVALID) {
+ ret = -EINVAL;
+ } else {
+ config->format = format;
+ }
+
+ pcm_params_free(alsa_hw_params);
+ return ret;
}
/*
@@ -772,7 +1015,6 @@
ALOGV("usb:audio_hw::out out_set_parameters() keys:%s", kvpairs);
struct stream_out *out = (struct stream_out *)stream;
- struct audio_device *adev = out->dev;
struct str_parms *parms;
char value[32];
int param_val;
@@ -780,45 +1022,41 @@
int ret_value = 0;
parms = str_parms_create_str(kvpairs);
- pthread_mutex_lock(&adev->lock);
+ pthread_mutex_lock(&out->dev->lock);
+ pthread_mutex_lock(&out->lock);
bool recache_device_params = false;
param_val = str_parms_get_str(parms, "card", value, sizeof(value));
if (param_val >= 0) {
- adev->out_card = atoi(value);
+ out->profile->card = atoi(value);
recache_device_params = true;
}
param_val = str_parms_get_str(parms, "device", value, sizeof(value));
if (param_val >= 0) {
- adev->out_device = atoi(value);
+ out->profile->device = atoi(value);
recache_device_params = true;
}
- if (recache_device_params && adev->out_card >= 0 && adev->out_device >= 0) {
- ret_value = read_alsa_device_config(adev->out_card, adev->out_device, PCM_OUT,
- &cached_output_hardware_config);
+ if (recache_device_params && out->profile->card >= 0 && out->profile->device >= 0) {
+ ret_value = read_alsa_device_config(out->profile, &cached_output_hardware_config);
output_hardware_config_is_cached = (ret_value == 0);
}
- pthread_mutex_unlock(&adev->lock);
+ pthread_mutex_unlock(&out->lock);
+ pthread_mutex_unlock(&out->dev->lock);
str_parms_destroy(parms);
return ret_value;
}
-/*TODO it seems like both out_get_parameters() and in_get_parameters()
- could be written in terms of a get_device_parameters(io_type) */
-
-static char * out_get_parameters(const struct audio_stream *stream, const char *keys)
+static char * device_get_parameters(struct audio_device_profile * dev_profile, const char *keys)
{
- ALOGV("usb:audio_hw::out out_get_parameters() keys:%s", keys);
+ ALOGV("usb:audio_hw::device_get_parameters() keys:%s", keys);
- struct stream_out *out = (struct stream_out *) stream;
- struct audio_device *adev = out->dev;
-
- if (adev->out_card < 0 || adev->out_device < 0)
+ if (dev_profile->card < 0 || dev_profile->device < 0) {
return strdup("");
+ }
unsigned min, max;
@@ -830,58 +1068,74 @@
int buffer_size = sizeof(buffer) / sizeof(buffer[0]);
char* result_str = NULL;
- struct pcm_params * alsa_hw_params = pcm_params_get(adev->out_card, adev->out_device, PCM_OUT);
+ struct pcm_params * alsa_hw_params =
+ pcm_params_get(dev_profile->card, dev_profile->device, dev_profile->direction);
// These keys are from hardware/libhardware/include/audio.h
// supported sample rates
if (str_parms_has_key(query, AUDIO_PARAMETER_STREAM_SUP_SAMPLING_RATES)) {
- // pcm_hw_params doesn't have a list of supported samples rates, just a min and a max, so
- // if they are different, return a list containing those two values, otherwise just the one.
min = pcm_params_get_min(alsa_hw_params, PCM_PARAM_RATE);
max = pcm_params_get_max(alsa_hw_params, PCM_PARAM_RATE);
- num_written = snprintf(buffer, buffer_size, "%u", min);
- if (min != max) {
- snprintf(buffer + num_written, buffer_size - num_written, "|%u", max);
- }
- str_parms_add_str(result, AUDIO_PARAMETER_STREAM_SUP_SAMPLING_RATES,
- buffer);
+
+ char* rates_list = enum_std_sample_rates(dev_profile, min, max);
+ str_parms_add_str(result, AUDIO_PARAMETER_STREAM_SUP_SAMPLING_RATES, rates_list);
+ free(rates_list);
} // AUDIO_PARAMETER_STREAM_SUP_SAMPLING_RATES
// supported channel counts
if (str_parms_has_key(query, AUDIO_PARAMETER_STREAM_SUP_CHANNELS)) {
- // Similarly for output channels count
- /* TODO - This is wrong, we need format strings, not numbers (another CL) */
- min = pcm_params_get_min(alsa_hw_params, PCM_PARAM_CHANNELS);
- max = pcm_params_get_max(alsa_hw_params, PCM_PARAM_CHANNELS);
- num_written = snprintf(buffer, buffer_size, "%u", min);
- if (min != max) {
- snprintf(buffer + num_written, buffer_size - num_written, "|%u", max);
- }
- str_parms_add_str(result, AUDIO_PARAMETER_STREAM_SUP_CHANNELS, buffer);
+ // TODO remove this hack when it is superceeded by proper multi-channel support
+ str_parms_add_str(result, AUDIO_PARAMETER_STREAM_SUP_CHANNELS,
+ dev_profile->direction == PCM_OUT
+ ? "AUDIO_CHANNEL_OUT_STEREO"
+ : "AUDIO_CHANNEL_IN_STEREO");
} // AUDIO_PARAMETER_STREAM_SUP_CHANNELS
// supported sample formats
if (str_parms_has_key(query, AUDIO_PARAMETER_STREAM_SUP_FORMATS)) {
- char * format_params =
- get_format_str_for_mask(pcm_params_get_mask(alsa_hw_params, PCM_PARAM_FORMAT));
- str_parms_add_str(result, AUDIO_PARAMETER_STREAM_SUP_FORMATS, format_params);
- free(format_params);
+ // TODO remove this hack when we have support for input in non PCM16 formats
+ if (dev_profile->direction == PCM_IN) {
+ str_parms_add_str(result, AUDIO_PARAMETER_STREAM_SUP_FORMATS, "AUDIO_FORMAT_PCM_16_BIT");
+ } else {
+ struct pcm_mask * format_mask = pcm_params_get_mask(alsa_hw_params, PCM_PARAM_FORMAT);
+ char * format_params = get_format_str_for_mask(format_mask);
+ str_parms_add_str(result, AUDIO_PARAMETER_STREAM_SUP_FORMATS, format_params);
+ free(format_params);
+ }
} // AUDIO_PARAMETER_STREAM_SUP_FORMATS
+ pcm_params_free(alsa_hw_params);
+
result_str = str_parms_to_str(result);
// done with these...
str_parms_destroy(query);
str_parms_destroy(result);
- ALOGV("usb:audio_hw::out out_get_parameters() = %s", result_str);
+ ALOGV("usb:audio_hw::device_get_parameters = %s", result_str);
return result_str;
}
+static char * out_get_parameters(const struct audio_stream *stream, const char *keys)
+{
+ ALOGV("usb:audio_hw::out out_get_parameters() keys:%s", keys);
+
+ struct stream_out *out = (struct stream_out *) stream;
+ pthread_mutex_lock(&out->dev->lock);
+ pthread_mutex_lock(&out->lock);
+
+ char * params_str = device_get_parameters(out->profile, keys);
+
+ pthread_mutex_unlock(&out->lock);
+ pthread_mutex_unlock(&out->dev->lock);
+
+ return params_str;
+}
+
static uint32_t out_get_latency(const struct audio_stream_out *stream)
{
- struct stream_out *out = (struct stream_out *) stream;
+ // struct stream_out *out = (struct stream_out *) stream;
/*TODO Do we need a term here for the USB latency (as reported in the USB descriptors)? */
uint32_t latency = (cached_output_hardware_config.period_size
@@ -898,13 +1152,13 @@
/* must be called with hw device and output stream mutexes locked */
static int start_output_stream(struct stream_out *out)
{
- struct audio_device *adev = out->dev;
int return_val = 0;
ALOGV("usb:audio_hw::out start_output_stream(card:%d device:%d)",
- adev->out_card, adev->out_device);
+ out->profile->card, out->profile->device);
- out->pcm = pcm_open(adev->out_card, adev->out_device, PCM_OUT, &cached_output_hardware_config);
+ out->pcm = pcm_open(out->profile->card, out->profile->device, PCM_OUT,
+ &cached_output_hardware_config);
if (out->pcm == NULL) {
return -ENOMEM;
@@ -955,10 +1209,12 @@
int num_device_channels = cached_output_hardware_config.channels;
int num_req_channels = 2; /* always, for now */
if (num_device_channels != num_req_channels) {
+ audio_format_t audio_format = out_get_format(&(out->stream.common));
+ unsigned sample_size_in_bytes = audio_bytes_per_sample(audio_format);
num_write_buff_bytes =
- expand_channels_16(write_buff, num_req_channels,
- out->conversion_buffer, num_device_channels,
- num_write_buff_bytes / sizeof(short));
+ adjust_channels(write_buff, num_req_channels,
+ out->conversion_buffer, num_device_channels,
+ sample_size_in_bytes, num_write_buff_bytes);
write_buff = out->conversion_buffer;
}
@@ -1041,6 +1297,9 @@
out->dev = adev;
+ out->profile = &(adev->out_profile);
+ out->profile->direction = PCM_OUT;
+
if (output_hardware_config_is_cached) {
config->sample_rate = cached_output_hardware_config.rate;
@@ -1207,7 +1466,6 @@
ALOGV("usb: audio_hw::in in_set_parameters() keys:%s", kvpairs);
struct stream_in *in = (struct stream_in *)stream;
- struct audio_device *adev = in->dev;
struct str_parms *parms;
char value[32];
int param_val;
@@ -1215,112 +1473,49 @@
int ret_value = 0;
parms = str_parms_create_str(kvpairs);
- pthread_mutex_lock(&adev->lock);
+ pthread_mutex_lock(&in->dev->lock);
+ pthread_mutex_lock(&in->lock);
bool recache_device_params = false;
// Card/Device
param_val = str_parms_get_str(parms, "card", value, sizeof(value));
if (param_val >= 0) {
- adev->in_card = atoi(value);
+ in->profile->card = atoi(value);
recache_device_params = true;
}
param_val = str_parms_get_str(parms, "device", value, sizeof(value));
if (param_val >= 0) {
- adev->in_device = atoi(value);
+ in->profile->device = atoi(value);
recache_device_params = true;
}
- if (recache_device_params && adev->in_card >= 0 && adev->in_device >= 0) {
- ret_value = read_alsa_device_config(adev->in_card, adev->in_device,
- PCM_IN, &(cached_input_hardware_config));
+ if (recache_device_params && in->profile->card >= 0 && in->profile->device >= 0) {
+ ret_value = read_alsa_device_config(in->profile, &cached_input_hardware_config);
input_hardware_config_is_cached = (ret_value == 0);
}
- pthread_mutex_unlock(&adev->lock);
+ pthread_mutex_unlock(&in->lock);
+ pthread_mutex_unlock(&in->dev->lock);
str_parms_destroy(parms);
return ret_value;
}
-/*TODO it seems like both out_get_parameters() and in_get_parameters()
- could be written in terms of a get_device_parameters(io_type) */
-
static char * in_get_parameters(const struct audio_stream *stream, const char *keys) {
ALOGV("usb:audio_hw::in in_get_parameters() keys:%s", keys);
struct stream_in *in = (struct stream_in *)stream;
- struct audio_device *adev = in->dev;
+ pthread_mutex_lock(&in->dev->lock);
+ pthread_mutex_lock(&in->lock);
- if (adev->in_card < 0 || adev->in_device < 0)
- return strdup("");
+ char * params_str = device_get_parameters(in->profile, keys);
- struct pcm_params * alsa_hw_params = pcm_params_get(adev->in_card, adev->in_device, PCM_IN);
- if (alsa_hw_params == NULL)
- return strdup("");
+ pthread_mutex_unlock(&in->lock);
+ pthread_mutex_unlock(&in->dev->lock);
- struct str_parms *query = str_parms_create_str(keys);
- struct str_parms *result = str_parms_create();
-
- int num_written = 0;
- char buffer[256];
- int buffer_size = sizeof(buffer) / sizeof(buffer[0]);
- char* result_str = NULL;
-
- unsigned min, max;
-
- // These keys are from hardware/libhardware/include/audio.h
- // supported sample rates
- if (str_parms_has_key(query, AUDIO_PARAMETER_STREAM_SUP_SAMPLING_RATES)) {
- // pcm_hw_params doesn't have a list of supported samples rates, just a min and a max, so
- // if they are different, return a list containing those two values, otherwise just the one.
- min = pcm_params_get_min(alsa_hw_params, PCM_PARAM_RATE);
- max = pcm_params_get_max(alsa_hw_params, PCM_PARAM_RATE);
- num_written = snprintf(buffer, buffer_size, "%u", min);
- if (min != max) {
- snprintf(buffer + num_written, buffer_size - num_written, "|%u", max);
- }
- str_parms_add_str(result, AUDIO_PARAMETER_STREAM_SAMPLING_RATE, buffer);
- } // AUDIO_PARAMETER_STREAM_SUP_SAMPLING_RATES
-
- // supported channel counts
- if (str_parms_has_key(query, AUDIO_PARAMETER_STREAM_SUP_CHANNELS)) {
- // Similarly for output channels count
- // TODO This is wrong, we need format strings, not numbers (another CL)
- min = pcm_params_get_min(alsa_hw_params, PCM_PARAM_CHANNELS);
- max = pcm_params_get_max(alsa_hw_params, PCM_PARAM_CHANNELS);
- num_written = snprintf(buffer, buffer_size, "%u", min);
- if (min != max) {
- snprintf(buffer + num_written, buffer_size - num_written, "|%u", max);
- }
- str_parms_add_str(result, AUDIO_PARAMETER_STREAM_CHANNELS, buffer);
- } // AUDIO_PARAMETER_STREAM_SUP_CHANNELS
-
- // supported sample formats
- if (str_parms_has_key(query, AUDIO_PARAMETER_STREAM_SUP_FORMATS)) {
- struct pcm_mask * format_mask = pcm_params_get_mask(alsa_hw_params, PCM_PARAM_FORMAT);
- char * format_params = get_format_str_for_mask(format_mask);
- if (!mask_has_pcm_16(format_mask)) {
- /* For now, always support PCM_16 and convert locally if necessary */
- char buff[256];
- snprintf(buff, sizeof(buff), "AUDIO_FORMAT_PCM_16_BIT|%s", format_params);
- free(format_params);
- str_parms_add_str(result, AUDIO_PARAMETER_STREAM_SUP_FORMATS, buff);
- } else {
- str_parms_add_str(result, AUDIO_PARAMETER_STREAM_SUP_FORMATS, format_params);
- }
- } // AUDIO_PARAMETER_STREAM_SUP_FORMATS
-
- result_str = str_parms_to_str(result);
-
- // done with these...
- str_parms_destroy(query);
- str_parms_destroy(result);
-
- ALOGV("usb:audio_hw::in in_get_parameters() = %s", result_str);
-
- return result_str;
+ return params_str;
}
static int in_add_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
@@ -1340,13 +1535,13 @@
/* must be called with hw device and output stream mutexes locked */
static int start_input_stream(struct stream_in *in) {
- struct audio_device *adev = in->dev;
int return_val = 0;
ALOGV("usb:audio_hw::start_input_stream(card:%d device:%d)",
- adev->in_card, adev->in_device);
+ in->profile->card, in->profile->device);
- in->pcm = pcm_open(adev->in_card, adev->in_device, PCM_IN, &cached_input_hardware_config);
+ in->pcm = pcm_open(in->profile->card, in->profile->device, PCM_IN,
+ &cached_input_hardware_config);
if (in->pcm == NULL) {
ALOGE("usb:audio_hw pcm_open() in->pcm == NULL");
return -ENOMEM;
@@ -1436,16 +1631,14 @@
if (num_device_channels != num_req_channels) {
out_buff = buffer;
/* Num Channels conversion */
- if (num_device_channels < num_req_channels) {
+ if (num_device_channels != num_req_channels) {
+ audio_format_t audio_format = in_get_format(&(in->stream.common));
+ unsigned sample_size_in_bytes = audio_bytes_per_sample(audio_format);
+
num_read_buff_bytes =
- expand_channels_16(read_buff, num_device_channels,
- out_buff, num_req_channels,
- num_read_buff_bytes / sizeof(short));
- } else {
- num_read_buff_bytes =
- contract_channels_16(read_buff, num_device_channels,
- out_buff, num_req_channels,
- num_read_buff_bytes / sizeof(short));
+ adjust_channels(read_buff, num_device_channels,
+ out_buff, num_req_channels,
+ sample_size_in_bytes, num_read_buff_bytes);
}
}
}
@@ -1466,7 +1659,8 @@
audio_io_handle_t handle,
audio_devices_t devices,
struct audio_config *config,
- struct audio_stream_in **stream_in)
+ struct audio_stream_in **stream_in,
+ audio_input_flags_t flags __unused)
{
ALOGV("usb: in adev_open_input_stream() rate:%" PRIu32 ", chanMask:0x%" PRIX32 ", fmt:%" PRIu8,
config->sample_rate, config->channel_mask, config->format);
@@ -1499,6 +1693,9 @@
in->dev = (struct audio_device *)dev;
+ in->profile = &(in->dev->in_profile);
+ in->profile->direction = PCM_IN;
+
if (!input_hardware_config_is_cached) {
// just return defaults until we can actually query the device.
cached_input_hardware_config = default_alsa_in_config;
diff --git a/tests/hardware/struct-offset.cpp b/tests/hardware/struct-offset.cpp
index 8e5aa40..2354408 100644
--- a/tests/hardware/struct-offset.cpp
+++ b/tests/hardware/struct-offset.cpp
@@ -167,7 +167,9 @@
CHECK_MEMBER_AT(hwc_composer_device_1_t, dump, 88, 168);
CHECK_MEMBER_AT(hwc_composer_device_1_t, getDisplayConfigs, 92, 176);
CHECK_MEMBER_AT(hwc_composer_device_1_t, getDisplayAttributes, 96, 184);
- CHECK_MEMBER_AT(hwc_composer_device_1_t, reserved_proc, 100, 192);
+ CHECK_MEMBER_AT(hwc_composer_device_1_t, getActiveConfig, 100, 192);
+ CHECK_MEMBER_AT(hwc_composer_device_1_t, setActiveConfig, 104, 200);
+ CHECK_MEMBER_AT(hwc_composer_device_1_t, reserved_proc, 108, 208);
//Types defined in gralloc.h
CHECK_MEMBER_AT(gralloc_module_t, common, 0, 0);
diff --git a/tests/hwc/test-arrows.c b/tests/hwc/test-arrows.c
index a35faa7..12e7c8f 100644
--- a/tests/hwc/test-arrows.c
+++ b/tests/hwc/test-arrows.c
@@ -140,7 +140,7 @@
int main(int argc, char **argv) {
EGLDisplay display;
EGLSurface surface;
- int w, h, count;
+ int w, h, count = 0;
if (argc > 1)
count = atoi(argv[1]);