2014-09-26 13:42:14

by Szymon Janc

[permalink] [raw]
Subject: [PATCH 1/5] android/client: Simplify PCM handling function in SCO HAL

Those functions operates on aligned buffers so there is no need for
unaligned memory access helpers.
---
android/client/if-sco.c | 21 +++++++--------------
1 file changed, 7 insertions(+), 14 deletions(-)

diff --git a/android/client/if-sco.c b/android/client/if-sco.c
index 7a89692..e7197b2 100644
--- a/android/client/if-sco.c
+++ b/android/client/if-sco.c
@@ -19,7 +19,6 @@
#include <unistd.h>
#include <math.h>

-#include "../src/shared/util.h"
#include "if-main.h"
#include "../hal-utils.h"

@@ -176,14 +175,11 @@ static void prepare_sample(void)

static void mono_to_stereo_pcm16(const int16_t *in, int16_t *out, size_t samples)
{
- int16_t mono;
size_t i;

for (i = 0; i < samples; i++) {
- mono = get_unaligned(&in[i]);
-
- put_unaligned(mono, &out[2 * i]);
- put_unaligned(mono, &out[2 * i + 1]);
+ out[2 * i] = in[i];
+ out[2 * i + 1] = in[i];
}
}

@@ -267,17 +263,14 @@ static void *playback_thread(void *data)
return NULL;
}

-static void write_stereo_pcm16(char *buffer, size_t len, FILE *out)
+static void write_stereo_pcm16(const short *input, size_t len, FILE *out)
{
- const int16_t *input = (const void *) buffer;
- int16_t sample[2];
+ short sample[2];
size_t i;

for (i = 0; i < len / 2; i++) {
- int16_t mono = get_unaligned(&input[i]);
-
- put_unaligned(mono, &sample[0]);
- put_unaligned(mono, &sample[1]);
+ sample[0] = input[i];
+ sample[1] = input[i];

fwrite(sample, sizeof(sample), 1, out);
}
@@ -319,7 +312,7 @@ static void *read_thread(void *data)
haltest_info("Read %zd bytes\n", len);

if (out) {
- write_stereo_pcm16((char *) buffer, len, out);
+ write_stereo_pcm16(buffer, len, out);
haltest_info("Written %zd bytes\n", len * 2);
}
} while (len);
--
1.9.1



2014-09-29 16:13:06

by Szymon Janc

[permalink] [raw]
Subject: Re: [PATCH 1/5] android/client: Simplify PCM handling function in SCO HAL

On Friday 26 September 2014 15:42:14 Szymon Janc wrote:
> Those functions operates on aligned buffers so there is no need for
> unaligned memory access helpers.
> ---
> android/client/if-sco.c | 21 +++++++--------------
> 1 file changed, 7 insertions(+), 14 deletions(-)
>
> diff --git a/android/client/if-sco.c b/android/client/if-sco.c
> index 7a89692..e7197b2 100644
> --- a/android/client/if-sco.c
> +++ b/android/client/if-sco.c
> @@ -19,7 +19,6 @@
> #include <unistd.h>
> #include <math.h>
>
> -#include "../src/shared/util.h"
> #include "if-main.h"
> #include "../hal-utils.h"
>
> @@ -176,14 +175,11 @@ static void prepare_sample(void)
>
> static void mono_to_stereo_pcm16(const int16_t *in, int16_t *out, size_t
> samples) {
> - int16_t mono;
> size_t i;
>
> for (i = 0; i < samples; i++) {
> - mono = get_unaligned(&in[i]);
> -
> - put_unaligned(mono, &out[2 * i]);
> - put_unaligned(mono, &out[2 * i + 1]);
> + out[2 * i] = in[i];
> + out[2 * i + 1] = in[i];
> }
> }
>
> @@ -267,17 +263,14 @@ static void *playback_thread(void *data)
> return NULL;
> }
>
> -static void write_stereo_pcm16(char *buffer, size_t len, FILE *out)
> +static void write_stereo_pcm16(const short *input, size_t len, FILE *out)
> {
> - const int16_t *input = (const void *) buffer;
> - int16_t sample[2];
> + short sample[2];
> size_t i;
>
> for (i = 0; i < len / 2; i++) {
> - int16_t mono = get_unaligned(&input[i]);
> -
> - put_unaligned(mono, &sample[0]);
> - put_unaligned(mono, &sample[1]);
> + sample[0] = input[i];
> + sample[1] = input[i];
>
> fwrite(sample, sizeof(sample), 1, out);
> }
> @@ -319,7 +312,7 @@ static void *read_thread(void *data)
> haltest_info("Read %zd bytes\n", len);
>
> if (out) {
> - write_stereo_pcm16((char *) buffer, len, out);
> + write_stereo_pcm16(buffer, len, out);
> haltest_info("Written %zd bytes\n", len * 2);
> }
> } while (len);

Pushed.

--
Szymon K. Janc
[email protected]

2014-09-26 13:42:18

by Szymon Janc

[permalink] [raw]
Subject: [PATCH 5/5] android/hal-audio: Use hal-utils helpers for unaligned access

---
android/hal-audio.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/android/hal-audio.c b/android/hal-audio.c
index 1bbc073..e70351e 100644
--- a/android/hal-audio.c
+++ b/android/hal-audio.c
@@ -35,7 +35,7 @@
#include "hal-log.h"
#include "hal-msg.h"
#include "hal-audio.h"
-#include "src/shared/util.h"
+#include "hal-utils.h"

#define FIXED_A2DP_PLAYBACK_LATENCY_MS 25

@@ -588,10 +588,10 @@ static void downmix_to_mono(struct a2dp_stream_out *out, const uint8_t *buffer,
frames = bytes / (2 * sizeof(int16_t));

for (i = 0; i < frames; i++) {
- int16_t l = le16_to_cpu(get_unaligned(&input[i * 2]));
- int16_t r = le16_to_cpu(get_unaligned(&input[i * 2 + 1]));
+ int16_t l = get_le16(&input[i * 2]);
+ int16_t r = get_le16(&input[i * 2 + 1]);

- put_unaligned(cpu_to_le16((l + r) / 2), &output[i]);
+ put_le16((l + r) / 2, &output[i]);
}
}

--
1.9.1


2014-09-26 13:42:16

by Szymon Janc

[permalink] [raw]
Subject: [PATCH 3/5] android/hal: Add simple helpers for unaligned memory access

In HALs we usually don't operate on unaligned memory. Only exception
are PCM stereo<->mono mixing scenarios in sco and audio HALs.
---
android/hal-utils.h | 20 ++++++++++++++++++++
1 file changed, 20 insertions(+)

diff --git a/android/hal-utils.h b/android/hal-utils.h
index a2ae0f4..ee0320c 100644
--- a/android/hal-utils.h
+++ b/android/hal-utils.h
@@ -15,6 +15,8 @@
*
*/

+#include <endian.h>
+
#include <hardware/bluetooth.h>

#define PLATFORM_VER(a,b,c) ((a << 16) | ( b << 8) | (c))
@@ -132,3 +134,21 @@ DECINTMAP(bt_bond_state_t);
DECINTMAP(bt_ssp_variant_t);
DECINTMAP(bt_property_type_t);
DECINTMAP(bt_cb_thread_evt);
+
+static inline uint16_t get_le16(const void *src)
+{
+ const struct __attribute__((packed)) {
+ uint16_t le16;
+ } *p = src;
+
+ return le16toh(p->le16);
+}
+
+static inline void put_le16(uint16_t val, void *dst)
+{
+ struct __attribute__((packed)) {
+ uint16_t le16;
+ } *p = dst;
+
+ p->le16 = htole16(val);
+}
--
1.9.1


2014-09-26 13:42:17

by Szymon Janc

[permalink] [raw]
Subject: [PATCH 4/5] android/hal-sco: Use hal-utils helpers for unaligned access

---
android/hal-sco.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/android/hal-sco.c b/android/hal-sco.c
index 8cb7a7c..91a3baf 100644
--- a/android/hal-sco.c
+++ b/android/hal-sco.c
@@ -29,7 +29,7 @@
#include <hardware/hardware.h>
#include <audio_utils/resampler.h>

-#include "../src/shared/util.h"
+#include "hal-utils.h"
#include "sco-msg.h"
#include "ipc-common.h"
#include "hal-log.h"
@@ -311,10 +311,10 @@ static void downmix_to_mono(struct sco_stream_out *out, const uint8_t *buffer,
size_t i;

for (i = 0; i < frame_num; i++) {
- int16_t l = le16_to_cpu(get_unaligned(&input[i * 2]));
- int16_t r = le16_to_cpu(get_unaligned(&input[i * 2 + 1]));
+ int16_t l = get_le16(&input[i * 2]);
+ int16_t r = get_le16(&input[i * 2 + 1]);

- put_unaligned(cpu_to_le16((l + r) >> 1), &output[i]);
+ put_le16((l + r) / 2, &output[i]);
}
}

--
1.9.1


2014-09-26 13:42:15

by Szymon Janc

[permalink] [raw]
Subject: [PATCH 2/5] android/hal-audio: Remove use of shared queue code

---
android/Android.mk | 1 -
android/Makefile.am | 3 +--
android/hal-audio.c | 56 +++++++++++++++++++++++++++++------------------------
3 files changed, 32 insertions(+), 28 deletions(-)

diff --git a/android/Android.mk b/android/Android.mk
index 30ba719..065ae1e 100644
--- a/android/Android.mk
+++ b/android/Android.mk
@@ -347,7 +347,6 @@ include $(BUILD_EXECUTABLE)
include $(CLEAR_VARS)

LOCAL_SRC_FILES := \
- bluez/src/shared/queue.c \
bluez/android/hal-audio.c \
bluez/android/hal-audio-sbc.c \
bluez/android/hal-audio-aptx.c \
diff --git a/android/Makefile.am b/android/Makefile.am
index 0ffc196..5a8a452 100644
--- a/android/Makefile.am
+++ b/android/Makefile.am
@@ -186,8 +186,7 @@ android_audio_a2dp_default_la_SOURCES = android/audio-msg.h \
android/system/audio.h
android_audio_a2dp_default_la_CFLAGS = $(AM_CFLAGS) -I$(srcdir)/android \
@SBC_CFLAGS@
-android_audio_a2dp_default_la_LIBADD = lib/libbluetooth-internal.la \
- src/libshared-mainloop.la @SBC_LIBS@
+android_audio_a2dp_default_la_LIBADD = @SBC_LIBS@
android_audio_a2dp_default_la_LDFLAGS = $(AM_LDFLAGS) -module -avoid-version \
-no-undefined -pthread -lrt

diff --git a/android/hal-audio.c b/android/hal-audio.c
index 66dc46a..1bbc073 100644
--- a/android/hal-audio.c
+++ b/android/hal-audio.c
@@ -36,7 +36,6 @@
#include "hal-msg.h"
#include "hal-audio.h"
#include "src/shared/util.h"
-#include "src/shared/queue.h"

#define FIXED_A2DP_PLAYBACK_LATENCY_MS 25

@@ -97,17 +96,18 @@ extern int clock_nanosleep(clockid_t clock_id, int flags,
struct timespec *remain);
#endif

-static const audio_codec_get_t audio_codecs[] = {
- codec_aptx,
- codec_sbc,
+static struct {
+ const audio_codec_get_t get_codec;
+ bool loaded;
+} audio_codecs[] = {
+ { .get_codec = codec_aptx, .loaded = false },
+ { .get_codec = codec_sbc, .loaded = false },
};

#define NUM_CODECS (sizeof(audio_codecs) / sizeof(audio_codecs[0]))

#define MAX_AUDIO_ENDPOINTS NUM_CODECS

-static struct queue *loaded_codecs;
-
struct audio_endpoint {
uint8_t id;
const struct audio_codec *codec;
@@ -423,10 +423,9 @@ struct register_state {
bool error;
};

-static void register_endpoint(void *data, void *user_data)
+static void register_endpoint(const struct audio_codec *codec,
+ struct register_state *state)
{
- struct audio_codec *codec = data;
- struct register_state *state = user_data;
struct audio_endpoint *ep = state->ep;

/* don't even try to register more endpoints if one failed */
@@ -451,11 +450,19 @@ static void register_endpoint(void *data, void *user_data)
static int register_endpoints(void)
{
struct register_state state;
+ unsigned int i;

state.ep = &audio_endpoints[0];
state.error = false;

- queue_foreach(loaded_codecs, register_endpoint, &state);
+ for (i = 0; i < NUM_CODECS; i++) {
+ const struct audio_codec *codec = audio_codecs[i].get_codec();
+
+ if (!audio_codecs[i].loaded)
+ continue;
+
+ register_endpoint(codec, &state);
+ }

return state.error ? AUDIO_STATUS_FAILED : AUDIO_STATUS_SUCCESS;
}
@@ -1293,24 +1300,26 @@ static int audio_dump(const audio_hw_device_t *device, int fd)
return -ENOSYS;
}

-static void unload_codec(void *data)
-{
- struct audio_codec *codec = data;
-
- if (codec->unload)
- codec->unload();
-}
-
static int audio_close(hw_device_t *device)
{
struct a2dp_audio_dev *a2dp_dev = (struct a2dp_audio_dev *)device;
+ unsigned int i;

DBG("");

unregister_endpoints();

- queue_destroy(loaded_codecs, unload_codec);
- loaded_codecs = NULL;
+ for (i = 0; i < NUM_CODECS; i++) {
+ const struct audio_codec *codec = audio_codecs[i].get_codec();
+
+ if (!audio_codecs[i].loaded)
+ continue;
+
+ if (codec->unload)
+ codec->unload();
+
+ audio_codecs[i].loaded = false;
+ }

shutdown(listen_sk, SHUT_RDWR);
shutdown(audio_sk, SHUT_RDWR);
@@ -1488,16 +1497,13 @@ static int audio_open(const hw_module_t *module, const char *name,
a2dp_dev->dev.close_input_stream = audio_close_input_stream;
a2dp_dev->dev.dump = audio_dump;

- loaded_codecs = queue_new();
-
for (i = 0; i < NUM_CODECS; i++) {
- audio_codec_get_t get_codec = audio_codecs[i];
- const struct audio_codec *codec = get_codec();
+ const struct audio_codec *codec = audio_codecs[i].get_codec();

if (codec->load && !codec->load())
continue;

- queue_push_tail(loaded_codecs, (void *) codec);
+ audio_codecs[i].loaded = true;
}

/*
--
1.9.1