| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805 |
- // SPDX-License-Identifier: Apache-2.0
- /*
- * Copyright (C) 2014 Intel Corporation
- *
- */
- #define _GNU_SOURCE
- #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
- };
|