public inbox for linux-bluetooth@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/8] haltest support for Audio SCO HAL testing
@ 2014-07-15  7:59 Andrei Emeltchenko
  2014-07-15  7:59 ` [PATCH 1/8] android/haltest: Add open/close input stream commands Andrei Emeltchenko
                   ` (8 more replies)
  0 siblings, 9 replies; 10+ messages in thread
From: Andrei Emeltchenko @ 2014-07-15  7:59 UTC (permalink / raw)
  To: linux-bluetooth

From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>

Helps to test Audio SCO HAL

Andrei Emeltchenko (8):
  android/haltest: Add open/close input stream commands
  android/haltest: Add read command.
  android/haltest: Add loop command
  android/haltest: Implement read to file
  android/haltest: Add sample rate parameter when opening audio streams
  android/haltest: Correct check for similar buffer size
  android/haltest: Add mono to stereo conversion for loopback
  android/haltest: Refactor stop and closing streams

 android/Android.mk      |   3 +
 android/client/if-sco.c | 291 ++++++++++++++++++++++++++++++++++++++++++++++--
 2 files changed, 283 insertions(+), 11 deletions(-)

-- 
1.9.1


^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH 1/8] android/haltest: Add open/close input stream commands
  2014-07-15  7:59 [PATCH 0/8] haltest support for Audio SCO HAL testing Andrei Emeltchenko
@ 2014-07-15  7:59 ` Andrei Emeltchenko
  2014-07-15  7:59 ` [PATCH 2/8] android/haltest: Add read command Andrei Emeltchenko
                   ` (7 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Andrei Emeltchenko @ 2014-07-15  7:59 UTC (permalink / raw)
  To: linux-bluetooth

From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>

---
 android/client/if-sco.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 51 insertions(+)

diff --git a/android/client/if-sco.c b/android/client/if-sco.c
index b7f5a80..c71d0b4 100644
--- a/android/client/if-sco.c
+++ b/android/client/if-sco.c
@@ -23,8 +23,10 @@
 
 audio_hw_device_t *if_audio_sco = NULL;
 static struct audio_stream_out *stream_out = NULL;
+static struct audio_stream_in *stream_in = NULL;
 
 static size_t buffer_size = 0;
+static size_t buffer_size_in = 0;
 static pthread_t play_thread = 0;
 static pthread_mutex_t outstream_mutex = PTHREAD_MUTEX_INITIALIZER;
 static pthread_mutex_t state_mutex = PTHREAD_MUTEX_INITIALIZER;
@@ -340,6 +342,53 @@ static void close_output_stream_p(int argc, const char **argv)
 	buffer_size = 0;
 }
 
+static void open_input_stream_p(int argc, const char **argv)
+{
+	int err;
+
+	RETURN_IF_NULL(if_audio_sco);
+
+	pthread_mutex_lock(&state_mutex);
+	if (current_state == STATE_PLAYING) {
+		haltest_error("Already playing!\n");
+		pthread_mutex_unlock(&state_mutex);
+		return;
+	}
+	pthread_mutex_unlock(&state_mutex);
+
+	err = if_audio_sco->open_input_stream(if_audio_sco,
+						0,
+						AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET,
+						NULL,
+						&stream_in);
+	if (err < 0) {
+		haltest_error("open output stream returned %d\n", err);
+		return;
+	}
+
+	buffer_size_in = stream_in->common.get_buffer_size(&stream_in->common);
+	if (buffer_size_in == 0)
+		haltest_error("Invalid buffer size received!\n");
+	else
+		haltest_info("Using buffer size: %zu\n", buffer_size_in);
+}
+
+static void close_input_stream_p(int argc, const char **argv)
+{
+	RETURN_IF_NULL(if_audio_sco);
+	RETURN_IF_NULL(stream_in);
+
+	stop_p(argc, argv);
+
+	haltest_info("Waiting for playback thread...\n");
+	pthread_join(play_thread, NULL);
+
+	if_audio_sco->close_input_stream(if_audio_sco, stream_in);
+
+	stream_in = NULL;
+	buffer_size_in = 0;
+}
+
 static void cleanup_p(int argc, const char **argv)
 {
 	int err;
@@ -499,6 +548,8 @@ static struct method methods[] = {
 	STD_METHOD(cleanup),
 	STD_METHOD(open_output_stream),
 	STD_METHOD(close_output_stream),
+	STD_METHOD(open_input_stream),
+	STD_METHOD(close_input_stream),
 	STD_METHODH(play, "<path to pcm file>"),
 	STD_METHOD(stop),
 	STD_METHOD(suspend),
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 2/8] android/haltest: Add read command.
  2014-07-15  7:59 [PATCH 0/8] haltest support for Audio SCO HAL testing Andrei Emeltchenko
  2014-07-15  7:59 ` [PATCH 1/8] android/haltest: Add open/close input stream commands Andrei Emeltchenko
@ 2014-07-15  7:59 ` Andrei Emeltchenko
  2014-07-15  7:59 ` [PATCH 3/8] android/haltest: Add loop command Andrei Emeltchenko
                   ` (6 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Andrei Emeltchenko @ 2014-07-15  7:59 UTC (permalink / raw)
  To: linux-bluetooth

From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>

Read command makes stream_in->read() call to Audio HAL.
---
 android/client/if-sco.c | 64 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 64 insertions(+)

diff --git a/android/client/if-sco.c b/android/client/if-sco.c
index c71d0b4..b4c3506 100644
--- a/android/client/if-sco.c
+++ b/android/client/if-sco.c
@@ -230,6 +230,45 @@ static void *playback_thread(void *data)
 	return NULL;
 }
 
+static void *read_thread(void *data)
+{
+	int (*filbuff_cb) (short*, void*) = feed_from_in;
+	short buffer[buffer_size / sizeof(short)];
+	size_t len = 0;
+	void *cb_data = NULL;
+
+	pthread_mutex_lock(&state_mutex);
+	current_state = STATE_PLAYING;
+	pthread_mutex_unlock(&state_mutex);
+
+	do {
+		pthread_mutex_lock(&state_mutex);
+
+		if (current_state == STATE_STOPPING) {
+			haltest_info("Detected stopping\n");
+			pthread_mutex_unlock(&state_mutex);
+			break;
+		} else if (current_state == STATE_SUSPENDED) {
+			pthread_mutex_unlock(&state_mutex);
+			usleep(500);
+			continue;
+		}
+
+		pthread_mutex_unlock(&state_mutex);
+
+		len = filbuff_cb(buffer, cb_data);
+		haltest_info("len %zd\n", len);
+	} while (len);
+
+	pthread_mutex_lock(&state_mutex);
+	current_state = STATE_STOPPED;
+	pthread_mutex_unlock(&state_mutex);
+
+	haltest_info("Done reading.\n");
+
+	return NULL;
+}
+
 static void play_p(int argc, const char **argv)
 {
 	const char *fname = NULL;
@@ -276,6 +315,30 @@ fail:
 		fclose(in);
 }
 
+static void read_p(int argc, const char **argv)
+{
+	RETURN_IF_NULL(if_audio_sco);
+	RETURN_IF_NULL(stream_in);
+
+	if (!buffer_size_in) {
+		haltest_error("Invalid buffer sizes. Streams opened\n");
+		return;
+	}
+
+	pthread_mutex_lock(&state_mutex);
+	if (current_state != STATE_STOPPED) {
+		haltest_error("Already playing or stream suspended!\n");
+		pthread_mutex_unlock(&state_mutex);
+		return;
+	}
+	pthread_mutex_unlock(&state_mutex);
+
+	if (pthread_create(&play_thread, NULL, read_thread,
+							stream_in) != 0)
+		haltest_error("Cannot create playback thread!\n");
+
+}
+
 static void stop_p(int argc, const char **argv)
 {
 	pthread_mutex_lock(&state_mutex);
@@ -551,6 +614,7 @@ static struct method methods[] = {
 	STD_METHOD(open_input_stream),
 	STD_METHOD(close_input_stream),
 	STD_METHODH(play, "<path to pcm file>"),
+	STD_METHOD(read),
 	STD_METHOD(stop),
 	STD_METHOD(suspend),
 	STD_METHOD(resume),
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 3/8] android/haltest: Add loop command
  2014-07-15  7:59 [PATCH 0/8] haltest support for Audio SCO HAL testing Andrei Emeltchenko
  2014-07-15  7:59 ` [PATCH 1/8] android/haltest: Add open/close input stream commands Andrei Emeltchenko
  2014-07-15  7:59 ` [PATCH 2/8] android/haltest: Add read command Andrei Emeltchenko
@ 2014-07-15  7:59 ` Andrei Emeltchenko
  2014-07-15  7:59 ` [PATCH 4/8] android/haltest: Implement read to file Andrei Emeltchenko
                   ` (5 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Andrei Emeltchenko @ 2014-07-15  7:59 UTC (permalink / raw)
  To: linux-bluetooth

From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>

loop command makes stream_in->read() and then stream_out->write(). At
the moment buffers shall be equal.
---
 android/client/if-sco.c | 45 ++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 42 insertions(+), 3 deletions(-)

diff --git a/android/client/if-sco.c b/android/client/if-sco.c
index b4c3506..39c3e3a 100644
--- a/android/client/if-sco.c
+++ b/android/client/if-sco.c
@@ -148,6 +148,11 @@ static int feed_from_generator(short *buffer, void *data)
 	return buffer_size;
 }
 
+static int feed_from_in(short *buffer, void *data)
+{
+	return stream_in->read(stream_in, buffer, buffer_size_in);
+}
+
 static void prepare_sample(void)
 {
 	int x;
@@ -179,8 +184,12 @@ static void *playback_thread(void *data)
 
 	/* Use file or fall back to generator */
 	if (in) {
-		filbuff_cb = feed_from_file;
-		cb_data = in;
+		if (data == stream_in)
+			filbuff_cb = feed_from_in;
+		else {
+			filbuff_cb = feed_from_file;
+			cb_data = in;
+		}
 	} else {
 		prepare_sample();
 		filbuff_cb = feed_from_generator;
@@ -218,7 +227,7 @@ static void *playback_thread(void *data)
 		pthread_mutex_unlock(&outstream_mutex);
 	} while (len && w_len > 0);
 
-	if (in)
+	if (in && data != stream_in)
 		fclose(in);
 
 	pthread_mutex_lock(&state_mutex);
@@ -315,6 +324,35 @@ fail:
 		fclose(in);
 }
 
+static void loop_p(int argc, const char **argv)
+{
+	RETURN_IF_NULL(if_audio_sco);
+	RETURN_IF_NULL(stream_out);
+	RETURN_IF_NULL(stream_in);
+
+	if (!buffer_size || !buffer_size_in) {
+		haltest_error("Invalid buffer sizes. Streams opened\n");
+		return;
+	}
+
+	if (buffer_size != buffer_size_in) {
+		haltest_error("read/write buffers differ, not supported\n");
+		return;
+	}
+
+	pthread_mutex_lock(&state_mutex);
+	if (current_state != STATE_STOPPED) {
+		haltest_error("Already playing or stream suspended!\n");
+		pthread_mutex_unlock(&state_mutex);
+		return;
+	}
+	pthread_mutex_unlock(&state_mutex);
+
+	if (pthread_create(&play_thread, NULL, playback_thread,
+							stream_in) != 0)
+		haltest_error("Cannot create playback thread!\n");
+}
+
 static void read_p(int argc, const char **argv)
 {
 	RETURN_IF_NULL(if_audio_sco);
@@ -615,6 +653,7 @@ static struct method methods[] = {
 	STD_METHOD(close_input_stream),
 	STD_METHODH(play, "<path to pcm file>"),
 	STD_METHOD(read),
+	STD_METHOD(loop),
 	STD_METHOD(stop),
 	STD_METHOD(suspend),
 	STD_METHOD(resume),
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 4/8] android/haltest: Implement read to file
  2014-07-15  7:59 [PATCH 0/8] haltest support for Audio SCO HAL testing Andrei Emeltchenko
                   ` (2 preceding siblings ...)
  2014-07-15  7:59 ` [PATCH 3/8] android/haltest: Add loop command Andrei Emeltchenko
@ 2014-07-15  7:59 ` Andrei Emeltchenko
  2014-07-15  7:59 ` [PATCH 5/8] android/haltest: Add sample rate parameter when opening audio streams Andrei Emeltchenko
                   ` (4 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Andrei Emeltchenko @ 2014-07-15  7:59 UTC (permalink / raw)
  To: linux-bluetooth

From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>

Reads data from stream_in and write to specified file.
---
 android/Android.mk      |  3 +++
 android/client/if-sco.c | 68 +++++++++++++++++++++++++++++++++++++++++--------
 2 files changed, 61 insertions(+), 10 deletions(-)

diff --git a/android/Android.mk b/android/Android.mk
index 667af14..0e319eb 100644
--- a/android/Android.mk
+++ b/android/Android.mk
@@ -174,6 +174,9 @@ LOCAL_C_INCLUDES += \
 	$(call include-path-for, system-core) \
 	$(call include-path-for, libhardware) \
 
+LOCAL_C_INCLUDES += \
+	$(LOCAL_PATH)/bluez/android \
+
 LOCAL_CFLAGS := $(BLUEZ_COMMON_CFLAGS)
 
 LOCAL_SHARED_LIBRARIES := libhardware
diff --git a/android/client/if-sco.c b/android/client/if-sco.c
index 39c3e3a..06ac6e8 100644
--- a/android/client/if-sco.c
+++ b/android/client/if-sco.c
@@ -15,6 +15,8 @@
  *
  */
 
+#include "../src/shared/util.h"
+
 #include "if-main.h"
 #include "../hal-utils.h"
 #include "pthread.h"
@@ -239,12 +241,29 @@ static void *playback_thread(void *data)
 	return NULL;
 }
 
+static void write_stereo_pcm16(char *buffer, size_t len, FILE *out)
+{
+	const int16_t *input = (const void *) buffer;
+	int16_t 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]);
+
+		fwrite(sample, sizeof(sample), 1, out);
+	}
+}
+
 static void *read_thread(void *data)
 {
 	int (*filbuff_cb) (short*, void*) = feed_from_in;
-	short buffer[buffer_size / sizeof(short)];
+	short buffer[buffer_size_in / sizeof(short)];
 	size_t len = 0;
 	void *cb_data = NULL;
+	FILE *out = data;
 
 	pthread_mutex_lock(&state_mutex);
 	current_state = STATE_PLAYING;
@@ -266,9 +285,18 @@ static void *read_thread(void *data)
 		pthread_mutex_unlock(&state_mutex);
 
 		len = filbuff_cb(buffer, cb_data);
-		haltest_info("len %zd\n", len);
+
+		haltest_info("Read %zd bytes\n", len);
+
+		if (out) {
+			write_stereo_pcm16((char *) buffer, len, out);
+			haltest_info("Written %zd bytes\n", len * 2);
+		}
 	} while (len);
 
+	if (out)
+		fclose(out);
+
 	pthread_mutex_lock(&state_mutex);
 	current_state = STATE_STOPPED;
 	pthread_mutex_unlock(&state_mutex);
@@ -355,14 +383,12 @@ static void loop_p(int argc, const char **argv)
 
 static void read_p(int argc, const char **argv)
 {
+	const char *fname = NULL;
+	FILE *out = NULL;
+
 	RETURN_IF_NULL(if_audio_sco);
 	RETURN_IF_NULL(stream_in);
 
-	if (!buffer_size_in) {
-		haltest_error("Invalid buffer sizes. Streams opened\n");
-		return;
-	}
-
 	pthread_mutex_lock(&state_mutex);
 	if (current_state != STATE_STOPPED) {
 		haltest_error("Already playing or stream suspended!\n");
@@ -371,10 +397,32 @@ static void read_p(int argc, const char **argv)
 	}
 	pthread_mutex_unlock(&state_mutex);
 
-	if (pthread_create(&play_thread, NULL, read_thread,
-							stream_in) != 0)
-		haltest_error("Cannot create playback thread!\n");
+	if (argc < 3) {
+		haltest_error("Invalid audio file path.\n");
+		haltest_info("Using read and through away\n");
+	} else {
+		fname = argv[2];
+		out = fopen(fname, "w");
+		if (!out) {
+			haltest_error("Cannot open file: %s\n", fname);
+			return;
+		}
 
+		haltest_info("Reading to file: %s\n", fname);
+	}
+
+	if (!buffer_size_in) {
+		haltest_error("Invalid buffer size.\n");
+		goto failed;
+	}
+
+	if (pthread_create(&play_thread, NULL, read_thread, out) != 0) {
+		haltest_error("Cannot create playback thread!\n");
+		goto failed;
+	}
+failed:
+	if (out)
+		fclose(out);
 }
 
 static void stop_p(int argc, const char **argv)
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 5/8] android/haltest: Add sample rate parameter when opening audio streams
  2014-07-15  7:59 [PATCH 0/8] haltest support for Audio SCO HAL testing Andrei Emeltchenko
                   ` (3 preceding siblings ...)
  2014-07-15  7:59 ` [PATCH 4/8] android/haltest: Implement read to file Andrei Emeltchenko
@ 2014-07-15  7:59 ` Andrei Emeltchenko
  2014-07-15  7:59 ` [PATCH 6/8] android/haltest: Correct check for similar buffer size Andrei Emeltchenko
                   ` (3 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Andrei Emeltchenko @ 2014-07-15  7:59 UTC (permalink / raw)
  To: linux-bluetooth

From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>

Opening input/output audio streams makes use of config with sample rate.
---
 android/client/if-sco.c | 46 ++++++++++++++++++++++++++++++++++++++++------
 1 file changed, 40 insertions(+), 6 deletions(-)

diff --git a/android/client/if-sco.c b/android/client/if-sco.c
index 06ac6e8..14b7dcc 100644
--- a/android/client/if-sco.c
+++ b/android/client/if-sco.c
@@ -445,6 +445,7 @@ static void stop_p(int argc, const char **argv)
 
 static void open_output_stream_p(int argc, const char **argv)
 {
+	struct audio_config *config;
 	int err;
 
 	RETURN_IF_NULL(if_audio_sco);
@@ -457,15 +458,28 @@ static void open_output_stream_p(int argc, const char **argv)
 	}
 	pthread_mutex_unlock(&state_mutex);
 
+	if (argc < 3) {
+		haltest_info("No sampling rate specified. Use default conf\n");
+		config = NULL;
+	} else {
+		config = calloc(1, sizeof(struct audio_config));
+		if (!config)
+			return;
+
+		config->sample_rate = atoi(argv[2]);
+		config->channel_mask = AUDIO_CHANNEL_OUT_STEREO;
+		config->format = AUDIO_FORMAT_PCM_16_BIT;
+	}
+
 	err = if_audio_sco->open_output_stream(if_audio_sco,
 						0,
 						AUDIO_DEVICE_OUT_ALL_SCO,
 						AUDIO_OUTPUT_FLAG_NONE,
-						NULL,
+						config,
 						&stream_out);
 	if (err < 0) {
 		haltest_error("open output stream returned %d\n", err);
-		return;
+		goto failed;
 	}
 
 	buffer_size = stream_out->common.get_buffer_size(&stream_out->common);
@@ -473,6 +487,9 @@ static void open_output_stream_p(int argc, const char **argv)
 		haltest_error("Invalid buffer size received!\n");
 	else
 		haltest_info("Using buffer size: %zu\n", buffer_size);
+failed:
+	if (config)
+		free(config);
 }
 
 static void close_output_stream_p(int argc, const char **argv)
@@ -493,6 +510,7 @@ static void close_output_stream_p(int argc, const char **argv)
 
 static void open_input_stream_p(int argc, const char **argv)
 {
+	struct audio_config *config;
 	int err;
 
 	RETURN_IF_NULL(if_audio_sco);
@@ -505,14 +523,27 @@ static void open_input_stream_p(int argc, const char **argv)
 	}
 	pthread_mutex_unlock(&state_mutex);
 
+	if (argc < 3) {
+		haltest_info("No sampling rate specified. Use default conf\n");
+		config = NULL;
+	} else {
+		config = calloc(1, sizeof(struct audio_config));
+		if (!config)
+			return;
+
+		config->sample_rate = atoi(argv[2]);
+		config->channel_mask = AUDIO_CHANNEL_OUT_MONO;
+		config->format = AUDIO_FORMAT_PCM_16_BIT;
+	}
+
 	err = if_audio_sco->open_input_stream(if_audio_sco,
 						0,
 						AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET,
-						NULL,
+						config,
 						&stream_in);
 	if (err < 0) {
 		haltest_error("open output stream returned %d\n", err);
-		return;
+		goto failed;
 	}
 
 	buffer_size_in = stream_in->common.get_buffer_size(&stream_in->common);
@@ -520,6 +551,9 @@ static void open_input_stream_p(int argc, const char **argv)
 		haltest_error("Invalid buffer size received!\n");
 	else
 		haltest_info("Using buffer size: %zu\n", buffer_size_in);
+failed:
+	if (config)
+		free(config);
 }
 
 static void close_input_stream_p(int argc, const char **argv)
@@ -695,9 +729,9 @@ static void init_check_p(int argc, const char **argv)
 static struct method methods[] = {
 	STD_METHOD(init),
 	STD_METHOD(cleanup),
-	STD_METHOD(open_output_stream),
+	STD_METHODH(open_output_stream, "sample_rate"),
 	STD_METHOD(close_output_stream),
-	STD_METHOD(open_input_stream),
+	STD_METHODH(open_input_stream, "sampling rate"),
 	STD_METHOD(close_input_stream),
 	STD_METHODH(play, "<path to pcm file>"),
 	STD_METHOD(read),
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 6/8] android/haltest: Correct check for similar buffer size
  2014-07-15  7:59 [PATCH 0/8] haltest support for Audio SCO HAL testing Andrei Emeltchenko
                   ` (4 preceding siblings ...)
  2014-07-15  7:59 ` [PATCH 5/8] android/haltest: Add sample rate parameter when opening audio streams Andrei Emeltchenko
@ 2014-07-15  7:59 ` Andrei Emeltchenko
  2014-07-15  7:59 ` [PATCH 7/8] android/haltest: Add mono to stereo conversion for loopback Andrei Emeltchenko
                   ` (2 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Andrei Emeltchenko @ 2014-07-15  7:59 UTC (permalink / raw)
  To: linux-bluetooth

From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>

The new check takes into account number of channels.
---
 android/client/if-sco.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/android/client/if-sco.c b/android/client/if-sco.c
index 14b7dcc..0b884c3 100644
--- a/android/client/if-sco.c
+++ b/android/client/if-sco.c
@@ -354,16 +354,21 @@ fail:
 
 static void loop_p(int argc, const char **argv)
 {
+	int chan_out, chan_in;
+
 	RETURN_IF_NULL(if_audio_sco);
 	RETURN_IF_NULL(stream_out);
 	RETURN_IF_NULL(stream_in);
 
+	chan_out = popcount(stream_out->common.get_channels(&stream_out->common));
+	chan_in = popcount(stream_in->common.get_channels(&stream_in->common));
+
 	if (!buffer_size || !buffer_size_in) {
 		haltest_error("Invalid buffer sizes. Streams opened\n");
 		return;
 	}
 
-	if (buffer_size != buffer_size_in) {
+	if (buffer_size / chan_out != buffer_size_in / chan_in) {
 		haltest_error("read/write buffers differ, not supported\n");
 		return;
 	}
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 7/8] android/haltest: Add mono to stereo conversion for loopback
  2014-07-15  7:59 [PATCH 0/8] haltest support for Audio SCO HAL testing Andrei Emeltchenko
                   ` (5 preceding siblings ...)
  2014-07-15  7:59 ` [PATCH 6/8] android/haltest: Correct check for similar buffer size Andrei Emeltchenko
@ 2014-07-15  7:59 ` Andrei Emeltchenko
  2014-07-15  7:59 ` [PATCH 8/8] android/haltest: Refactor stop and closing streams Andrei Emeltchenko
  2014-07-16 10:06 ` [PATCH 0/8] haltest support for Audio SCO HAL testing Szymon Janc
  8 siblings, 0 replies; 10+ messages in thread
From: Andrei Emeltchenko @ 2014-07-15  7:59 UTC (permalink / raw)
  To: linux-bluetooth

From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>

---
 android/client/if-sco.c | 28 +++++++++++++++++++++++++++-
 1 file changed, 27 insertions(+), 1 deletion(-)

diff --git a/android/client/if-sco.c b/android/client/if-sco.c
index 0b884c3..0e27a9d 100644
--- a/android/client/if-sco.c
+++ b/android/client/if-sco.c
@@ -174,10 +174,24 @@ static void prepare_sample(void)
 	sample_pos = 0;
 }
 
+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]);
+	}
+}
+
 static void *playback_thread(void *data)
 {
 	int (*filbuff_cb) (short*, void*);
 	short buffer[buffer_size / sizeof(short)];
+	short buffer_in[buffer_size_in / sizeof(short)];
 	size_t len = 0;
 	ssize_t w_len = 0;
 	FILE *in = data;
@@ -217,7 +231,19 @@ static void *playback_thread(void *data)
 
 		pthread_mutex_unlock(&state_mutex);
 
-		len = filbuff_cb(buffer, cb_data);
+		if (data && data == stream_in) {
+			int chan_in = popcount(stream_in->common.get_channels(&stream_in->common));
+			int chan_out = popcount(stream_out->common.get_channels(&stream_out->common));
+
+			len = filbuff_cb(buffer_in, cb_data);
+
+			if (chan_in == 1 && chan_out == 2) {
+				mono_to_stereo_pcm16(buffer_in,
+							buffer,
+							buffer_size_in / 2);
+			}
+		} else
+			len = filbuff_cb(buffer, cb_data);
 
 		pthread_mutex_lock(&outstream_mutex);
 		if (!stream_out) {
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 8/8] android/haltest: Refactor stop and closing streams
  2014-07-15  7:59 [PATCH 0/8] haltest support for Audio SCO HAL testing Andrei Emeltchenko
                   ` (6 preceding siblings ...)
  2014-07-15  7:59 ` [PATCH 7/8] android/haltest: Add mono to stereo conversion for loopback Andrei Emeltchenko
@ 2014-07-15  7:59 ` Andrei Emeltchenko
  2014-07-16 10:06 ` [PATCH 0/8] haltest support for Audio SCO HAL testing Szymon Janc
  8 siblings, 0 replies; 10+ messages in thread
From: Andrei Emeltchenko @ 2014-07-15  7:59 UTC (permalink / raw)
  To: linux-bluetooth

From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>

---
 android/client/if-sco.c | 18 ++++++++++--------
 1 file changed, 10 insertions(+), 8 deletions(-)

diff --git a/android/client/if-sco.c b/android/client/if-sco.c
index 0e27a9d..456c529 100644
--- a/android/client/if-sco.c
+++ b/android/client/if-sco.c
@@ -458,6 +458,9 @@ failed:
 
 static void stop_p(int argc, const char **argv)
 {
+	RETURN_IF_NULL(if_audio_sco);
+	RETURN_IF_NULL(play_thread);
+
 	pthread_mutex_lock(&state_mutex);
 	if (current_state == STATE_STOPPED || current_state == STATE_STOPPING) {
 		pthread_mutex_unlock(&state_mutex);
@@ -467,6 +470,9 @@ static void stop_p(int argc, const char **argv)
 	current_state = STATE_STOPPING;
 	pthread_mutex_unlock(&state_mutex);
 
+	pthread_join(play_thread, NULL);
+	play_thread = 0;
+
 	pthread_mutex_lock(&outstream_mutex);
 	stream_out->common.standby(&stream_out->common);
 	pthread_mutex_unlock(&outstream_mutex);
@@ -528,10 +534,8 @@ static void close_output_stream_p(int argc, const char **argv)
 	RETURN_IF_NULL(if_audio_sco);
 	RETURN_IF_NULL(stream_out);
 
-	stop_p(argc, argv);
-
-	haltest_info("Waiting for playback thread...\n");
-	pthread_join(play_thread, NULL);
+	if (play_thread)
+		stop_p(argc, argv);
 
 	if_audio_sco->close_output_stream(if_audio_sco, stream_out);
 
@@ -592,10 +596,8 @@ static void close_input_stream_p(int argc, const char **argv)
 	RETURN_IF_NULL(if_audio_sco);
 	RETURN_IF_NULL(stream_in);
 
-	stop_p(argc, argv);
-
-	haltest_info("Waiting for playback thread...\n");
-	pthread_join(play_thread, NULL);
+	if (play_thread)
+		stop_p(argc, argv);
 
 	if_audio_sco->close_input_stream(if_audio_sco, stream_in);
 
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [PATCH 0/8] haltest support for Audio SCO HAL testing
  2014-07-15  7:59 [PATCH 0/8] haltest support for Audio SCO HAL testing Andrei Emeltchenko
                   ` (7 preceding siblings ...)
  2014-07-15  7:59 ` [PATCH 8/8] android/haltest: Refactor stop and closing streams Andrei Emeltchenko
@ 2014-07-16 10:06 ` Szymon Janc
  8 siblings, 0 replies; 10+ messages in thread
From: Szymon Janc @ 2014-07-16 10:06 UTC (permalink / raw)
  To: Andrei Emeltchenko; +Cc: linux-bluetooth

Hi Andrei,

On Tuesday 15 of July 2014 10:59:19 Andrei Emeltchenko wrote:
> From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
> 
> Helps to test Audio SCO HAL
> 
> Andrei Emeltchenko (8):
>   android/haltest: Add open/close input stream commands
>   android/haltest: Add read command.
>   android/haltest: Add loop command
>   android/haltest: Implement read to file
>   android/haltest: Add sample rate parameter when opening audio streams
>   android/haltest: Correct check for similar buffer size
>   android/haltest: Add mono to stereo conversion for loopback
>   android/haltest: Refactor stop and closing streams
> 
>  android/Android.mk      |   3 +
>  android/client/if-sco.c | 291 ++++++++++++++++++++++++++++++++++++++++++++++--
>  2 files changed, 283 insertions(+), 11 deletions(-)
> 

All patches applied. Thanks.

(I've changed android/haltest to android/client in commits messages)

-- 
Best regards, 
Szymon Janc

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2014-07-16 10:06 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-07-15  7:59 [PATCH 0/8] haltest support for Audio SCO HAL testing Andrei Emeltchenko
2014-07-15  7:59 ` [PATCH 1/8] android/haltest: Add open/close input stream commands Andrei Emeltchenko
2014-07-15  7:59 ` [PATCH 2/8] android/haltest: Add read command Andrei Emeltchenko
2014-07-15  7:59 ` [PATCH 3/8] android/haltest: Add loop command Andrei Emeltchenko
2014-07-15  7:59 ` [PATCH 4/8] android/haltest: Implement read to file Andrei Emeltchenko
2014-07-15  7:59 ` [PATCH 5/8] android/haltest: Add sample rate parameter when opening audio streams Andrei Emeltchenko
2014-07-15  7:59 ` [PATCH 6/8] android/haltest: Correct check for similar buffer size Andrei Emeltchenko
2014-07-15  7:59 ` [PATCH 7/8] android/haltest: Add mono to stereo conversion for loopback Andrei Emeltchenko
2014-07-15  7:59 ` [PATCH 8/8] android/haltest: Refactor stop and closing streams Andrei Emeltchenko
2014-07-16 10:06 ` [PATCH 0/8] haltest support for Audio SCO HAL testing Szymon Janc

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox