/*
 * Copyright (C) 2014 Intel Corporation
 *
 * 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.
 *
 */

#include <pthread.h>
#include <unistd.h>
#include <math.h>

#include "if-main.h"
#include "../hal-utils.h"

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;

enum state {
	STATE_STOPPED,
	STATE_STOPPING,
	STATE_PLAYING,
	STATE_SUSPENDED,
	STATE_MAX
};

SINTMAP(audio_channel_mask_t, -1, "(AUDIO_CHANNEL_INVALID)")
	DELEMENT(AUDIO_CHANNEL_OUT_FRONT_LEFT),
	DELEMENT(AUDIO_CHANNEL_OUT_FRONT_RIGHT),
	DELEMENT(AUDIO_CHANNEL_OUT_FRONT_CENTER),
	DELEMENT(AUDIO_CHANNEL_OUT_LOW_FREQUENCY),
	DELEMENT(AUDIO_CHANNEL_OUT_BACK_LEFT),
	DELEMENT(AUDIO_CHANNEL_OUT_BACK_RIGHT),
	DELEMENT(AUDIO_CHANNEL_OUT_FRONT_LEFT_OF_CENTER),
	DELEMENT(AUDIO_CHANNEL_OUT_FRONT_RIGHT_OF_CENTER),
	DELEMENT(AUDIO_CHANNEL_OUT_BACK_CENTER),
	DELEMENT(AUDIO_CHANNEL_OUT_SIDE_LEFT),
	DELEMENT(AUDIO_CHANNEL_OUT_SIDE_RIGHT),
	DELEMENT(AUDIO_CHANNEL_OUT_TOP_CENTER),
	DELEMENT(AUDIO_CHANNEL_OUT_TOP_FRONT_LEFT),
	DELEMENT(AUDIO_CHANNEL_OUT_TOP_FRONT_CENTER),
	DELEMENT(AUDIO_CHANNEL_OUT_TOP_FRONT_RIGHT),
	DELEMENT(AUDIO_CHANNEL_OUT_TOP_BACK_LEFT),
	DELEMENT(AUDIO_CHANNEL_OUT_TOP_BACK_CENTER),
	DELEMENT(AUDIO_CHANNEL_OUT_TOP_BACK_RIGHT),
	DELEMENT(AUDIO_CHANNEL_OUT_MONO),
	DELEMENT(AUDIO_CHANNEL_OUT_STEREO),
	DELEMENT(AUDIO_CHANNEL_OUT_QUAD),
#if ANDROID_VERSION < PLATFORM_VER(5, 0, 0)
	DELEMENT(AUDIO_CHANNEL_OUT_SURROUND),
#else
	DELEMENT(AUDIO_CHANNEL_OUT_QUAD_BACK),
	DELEMENT(AUDIO_CHANNEL_OUT_QUAD_SIDE),
	DELEMENT(AUDIO_CHANNEL_OUT_5POINT1_BACK),
	DELEMENT(AUDIO_CHANNEL_OUT_5POINT1_SIDE),
#endif
	DELEMENT(AUDIO_CHANNEL_OUT_5POINT1),
	DELEMENT(AUDIO_CHANNEL_OUT_7POINT1),
	DELEMENT(AUDIO_CHANNEL_OUT_ALL),
	DELEMENT(AUDIO_CHANNEL_OUT_FRONT_LEFT),
	DELEMENT(AUDIO_CHANNEL_OUT_FRONT_LEFT),
	DELEMENT(AUDIO_CHANNEL_OUT_FRONT_LEFT),
	DELEMENT(AUDIO_CHANNEL_OUT_FRONT_LEFT),
	DELEMENT(AUDIO_CHANNEL_OUT_FRONT_LEFT),
ENDMAP

SINTMAP(audio_format_t, -1, "(AUDIO_FORMAT_INVALID)")
	DELEMENT(AUDIO_FORMAT_DEFAULT),
	DELEMENT(AUDIO_FORMAT_PCM),
	DELEMENT(AUDIO_FORMAT_MP3),
	DELEMENT(AUDIO_FORMAT_AMR_NB),
	DELEMENT(AUDIO_FORMAT_AMR_WB),
	DELEMENT(AUDIO_FORMAT_AAC),
	DELEMENT(AUDIO_FORMAT_HE_AAC_V1),
	DELEMENT(AUDIO_FORMAT_HE_AAC_V2),
	DELEMENT(AUDIO_FORMAT_VORBIS),
	DELEMENT(AUDIO_FORMAT_MAIN_MASK),
	DELEMENT(AUDIO_FORMAT_SUB_MASK),
	DELEMENT(AUDIO_FORMAT_PCM_16_BIT),
	DELEMENT(AUDIO_FORMAT_PCM_8_BIT),
	DELEMENT(AUDIO_FORMAT_PCM_32_BIT),
	DELEMENT(AUDIO_FORMAT_PCM_8_24_BIT),
ENDMAP

static int current_state = STATE_STOPPED;

#define SAMPLERATE 44100
static short sample[SAMPLERATE];
static uint16_t sample_pos;

static void init_p(int argc, const char **argv)
{
	int err;
	const hw_module_t *module;
	audio_hw_device_t *device;

	err = hw_get_module_by_class(AUDIO_HARDWARE_MODULE_ID, "sco", &module);
	if (err) {
		haltest_error("hw_get_module_by_class returned %d\n", err);
		return;
	}

	err = audio_hw_device_open(module, &device);
	if (err) {
		haltest_error("audio_hw_device_open returned %d\n", err);
		return;
	}

	if_audio_sco = device;
}

static int feed_from_file(short *buffer, void *data)
{
	FILE *in = data;
	return fread(buffer, buffer_size, 1, in);
}

static int feed_from_generator(short *buffer, void *data)
{
	size_t i = 0;
	float volume = 0.5;
	float *freq = data;
	float f = 1;

	if (freq)
		f = *freq;

	/* buffer_size is in bytes but we are using buffer of shorts (2 bytes)*/
	for (i = 0; i < buffer_size / sizeof(*buffer) - 1;) {
		if (sample_pos >= SAMPLERATE)
			sample_pos = sample_pos % SAMPLERATE;

		/* Use the same sample for both channels */
		buffer[i++] = sample[sample_pos] * volume;
		buffer[i++] = sample[sample_pos] * volume;

		sample_pos += f;
	}

	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;
	double s;

	haltest_info("Preparing audio sample...\n");

	for (x = 0; x < SAMPLERATE; x++) {
		/* prepare sinusoidal 1Hz sample */
		s = (2.0 * 3.14159) * ((double)x / SAMPLERATE);
		s = sin(s);

		/* remap <-1, 1> to signed 16bit PCM range */
		sample[x] = s * 32767;
	}

	sample_pos = 0;
}

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

	for (i = 0; i < samples; i++) {
		out[2 * i] = in[i];
		out[2 * i + 1] = in[i];
	}
}

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;
	void *cb_data = NULL;
	float freq = 440.0;

	/* Use file or fall back to generator */
	if (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;
		cb_data = &freq;
	}

	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);

		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) {
			pthread_mutex_unlock(&outstream_mutex);
			break;
		}

		w_len = stream_out->write(stream_out, buffer, buffer_size);
		pthread_mutex_unlock(&outstream_mutex);
	} while (len && w_len > 0);

	if (in && data != stream_in)
		fclose(in);

	pthread_mutex_lock(&state_mutex);
	current_state = STATE_STOPPED;
	pthread_mutex_unlock(&state_mutex);

	haltest_info("Done playing.\n");

	return NULL;
}

static void write_stereo_pcm16(const short *input, size_t len, FILE *out)
{
	short sample[2];
	size_t i;

	for (i = 0; i < len / 2; i++) {
		sample[0] = input[i];
		sample[1] = input[i];

		fwrite(sample, sizeof(sample), 1, out);
	}
}

static void *read_thread(void *data)
{
	int (*filbuff_cb) (short*, void*) = feed_from_in;
	short buffer[buffer_size_in / sizeof(short)];
	ssize_t len = 0;
	void *cb_data = NULL;
	FILE *out = data;

	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);
		if (len < 0) {
			haltest_error("Error receiving SCO data");
			break;
		}

		haltest_info("Read %zd bytes\n", len);

		if (out) {
			write_stereo_pcm16(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);

	haltest_info("Done reading.\n");

	return NULL;
}

static void play_p(int argc, const char **argv)
{
	const char *fname = NULL;
	FILE *in = NULL;

	RETURN_IF_NULL(if_audio_sco);
	RETURN_IF_NULL(stream_out);

	if (argc < 3) {
		haltest_error("Invalid audio file path.\n");
		haltest_info("Using sound generator.\n");
	} else {
		fname = argv[2];
		in = fopen(fname, "r");

		if (in == NULL) {
			haltest_error("Cannot open file: %s\n", fname);
			return;
		}
		haltest_info("Playing file: %s\n", fname);
	}

	if (buffer_size == 0) {
		haltest_error("Invalid buffer size. Was stream_out opened?\n");
		goto fail;
	}

	pthread_mutex_lock(&state_mutex);
	if (current_state != STATE_STOPPED) {
		haltest_error("Already playing or stream suspended!\n");
		pthread_mutex_unlock(&state_mutex);
		goto fail;
	}
	pthread_mutex_unlock(&state_mutex);

	if (pthread_create(&play_thread, NULL, playback_thread, in) != 0) {
		haltest_error("Cannot create playback thread!\n");
		goto fail;
	}

	return;
fail:
	if (in)
		fclose(in);
}

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 / chan_out != buffer_size_in / chan_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)
{
	const char *fname = NULL;
	FILE *out = NULL;

	RETURN_IF_NULL(if_audio_sco);
	RETURN_IF_NULL(stream_in);

	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 (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;
	}

	return;
failed:
	if (out)
		fclose(out);
}

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);
		return;
	}

	if (stream_out) {
		pthread_mutex_lock(&outstream_mutex);
		stream_out->common.standby(&stream_out->common);
		pthread_mutex_unlock(&outstream_mutex);
	}

	current_state = STATE_STOPPING;
	pthread_mutex_unlock(&state_mutex);

	pthread_join(play_thread, NULL);
	play_thread = 0;

	haltest_info("Ended %s\n", __func__);
}

static void open_output_stream_p(int argc, const char **argv)
{
	struct audio_config *config;
	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);

	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;
	}

#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0)
	err = if_audio_sco->open_output_stream(if_audio_sco,
						0,
						AUDIO_DEVICE_OUT_ALL_SCO,
						AUDIO_OUTPUT_FLAG_NONE,
						config,
						&stream_out, NULL);
#else
	err = if_audio_sco->open_output_stream(if_audio_sco,
						0,
						AUDIO_DEVICE_OUT_ALL_SCO,
						AUDIO_OUTPUT_FLAG_NONE,
						config,
						&stream_out);
#endif
	if (err < 0) {
		haltest_error("open output stream returned %d\n", err);
		goto failed;
	}

	buffer_size = stream_out->common.get_buffer_size(&stream_out->common);
	if (buffer_size == 0)
		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)
{
	RETURN_IF_NULL(if_audio_sco);
	RETURN_IF_NULL(stream_out);

	if (play_thread)
		stop_p(argc, argv);

	if_audio_sco->close_output_stream(if_audio_sco, stream_out);

	stream_out = NULL;
	buffer_size = 0;
}

static void open_input_stream_p(int argc, const char **argv)
{
	struct audio_config *config;
	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);

	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;
	}

#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0)
	err = if_audio_sco->open_input_stream(if_audio_sco,
						0,
						AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET,
						config,
						&stream_in, 0, NULL, 0);
#else
	err = if_audio_sco->open_input_stream(if_audio_sco,
						0,
						AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET,
						config,
						&stream_in);
#endif
	if (err < 0) {
		haltest_error("open output stream returned %d\n", err);
		goto failed;
	}

	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);
failed:
	if (config)
		free(config);
}

static void close_input_stream_p(int argc, const char **argv)
{
	RETURN_IF_NULL(if_audio_sco);
	RETURN_IF_NULL(stream_in);

	if (play_thread)
		stop_p(argc, argv);

	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;

	RETURN_IF_NULL(if_audio_sco);

	pthread_mutex_lock(&state_mutex);
	if (current_state != STATE_STOPPED) {
		pthread_mutex_unlock(&state_mutex);
		close_output_stream_p(0, NULL);
	} else {
		pthread_mutex_unlock(&state_mutex);
	}

	err = audio_hw_device_close(if_audio_sco);
	if (err < 0) {
		haltest_error("audio_hw_device_close returned %d\n", err);
		return;
	}

	if_audio_sco = NULL;
}

static void suspend_p(int argc, const char **argv)
{
	RETURN_IF_NULL(if_audio_sco);
	RETURN_IF_NULL(stream_out);

	pthread_mutex_lock(&state_mutex);
	if (current_state != STATE_PLAYING) {
		pthread_mutex_unlock(&state_mutex);
		return;
	}
	current_state = STATE_SUSPENDED;
	pthread_mutex_unlock(&state_mutex);

	pthread_mutex_lock(&outstream_mutex);
	stream_out->common.standby(&stream_out->common);
	pthread_mutex_unlock(&outstream_mutex);
}

static void resume_p(int argc, const char **argv)
{
	RETURN_IF_NULL(if_audio_sco);
	RETURN_IF_NULL(stream_out);

	pthread_mutex_lock(&state_mutex);
	if (current_state == STATE_SUSPENDED)
		current_state = STATE_PLAYING;
	pthread_mutex_unlock(&state_mutex);
}

static void get_latency_p(int argc, const char **argv)
{
	RETURN_IF_NULL(if_audio_sco);
	RETURN_IF_NULL(stream_out);

	haltest_info("Output audio stream latency: %d\n",
					stream_out->get_latency(stream_out));
}

static void get_buffer_size_p(int argc, const char **argv)
{
	RETURN_IF_NULL(if_audio_sco);
	RETURN_IF_NULL(stream_out);

	haltest_info("Current output buffer size: %zu\n",
		stream_out->common.get_buffer_size(&stream_out->common));
}

static void get_channels_p(int argc, const char **argv)
{
	audio_channel_mask_t channels;

	RETURN_IF_NULL(if_audio_sco);
	RETURN_IF_NULL(stream_out);

	channels = stream_out->common.get_channels(&stream_out->common);

	haltest_info("Channels: %s\n", audio_channel_mask_t2str(channels));
}

static void get_format_p(int argc, const char **argv)
{
	audio_format_t format;

	RETURN_IF_NULL(if_audio_sco);
	RETURN_IF_NULL(stream_out);

	format = stream_out->common.get_format(&stream_out->common);

	haltest_info("Format: %s\n", audio_format_t2str(format));
}

static void get_sample_rate_p(int argc, const char **argv)
{
	RETURN_IF_NULL(if_audio_sco);
	RETURN_IF_NULL(stream_out);

	haltest_info("Current sample rate: %d\n",
		stream_out->common.get_sample_rate(&stream_out->common));
}

static void get_parameters_p(int argc, const char **argv)
{
	const char *keystr;

	RETURN_IF_NULL(if_audio_sco);
	RETURN_IF_NULL(stream_out);

	if (argc < 3) {
		haltest_info("No keys given.\n");
		keystr = "";
	} else {
		keystr = argv[2];
	}

	haltest_info("Current parameters: %s\n",
			stream_out->common.get_parameters(&stream_out->common,
								keystr));
}

static void set_parameters_p(int argc, const char **argv)
{
	RETURN_IF_NULL(if_audio_sco);
	RETURN_IF_NULL(stream_out);

	if (argc < 3) {
		haltest_error("No key=value; pairs given.\n");
		return;
	}

	stream_out->common.set_parameters(&stream_out->common, argv[2]);
}

static void set_sample_rate_p(int argc, const char **argv)
{
	RETURN_IF_NULL(if_audio_sco);
	RETURN_IF_NULL(stream_out);

	if (argc < 3)
		return;

	stream_out->common.set_sample_rate(&stream_out->common, atoi(argv[2]));
}

static void init_check_p(int argc, const char **argv)
{
	RETURN_IF_NULL(if_audio_sco);

	haltest_info("Init check result: %d\n",
					if_audio_sco->init_check(if_audio_sco));
}

static struct method methods[] = {
	STD_METHOD(init),
	STD_METHOD(cleanup),
	STD_METHODH(open_output_stream, "sample_rate"),
	STD_METHOD(close_output_stream),
	STD_METHODH(open_input_stream, "sampling rate"),
	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),
	STD_METHOD(get_latency),
	STD_METHOD(get_buffer_size),
	STD_METHOD(get_channels),
	STD_METHOD(get_format),
	STD_METHOD(get_sample_rate),
	STD_METHODH(get_parameters, "<closing>"),
	STD_METHODH(set_parameters, "<closing=value>"),
	STD_METHODH(set_sample_rate, "<sample rate>"),
	STD_METHOD(init_check),
	END_METHOD
};

const struct interface sco_if = {
	.name = "sco",
	.methods = methods
};
