From patchwork Wed Jan 18 16:29:54 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Fitzgerald X-Patchwork-Id: 9524671 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 8DC676043A for ; Wed, 18 Jan 2017 20:09:34 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 719FB28632 for ; Wed, 18 Jan 2017 20:09:34 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 660D228635; Wed, 18 Jan 2017 20:09:34 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-1.9 required=2.0 tests=BAYES_00, RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id A9E8028632 for ; Wed, 18 Jan 2017 20:09:32 +0000 (UTC) Received: by alsa0.perex.cz (Postfix, from userid 1000) id CF2B9267765; Wed, 18 Jan 2017 21:09:30 +0100 (CET) Received: from alsa0.perex.cz (localhost [127.0.0.1]) by alsa0.perex.cz (Postfix) with ESMTP id B3D7D2668A2; Wed, 18 Jan 2017 21:07:11 +0100 (CET) X-Original-To: alsa-devel@alsa-project.org Delivered-To: alsa-devel@alsa-project.org Received: by alsa0.perex.cz (Postfix, from userid 1000) id 9A3062676B8; Wed, 18 Jan 2017 17:30:02 +0100 (CET) Received: from mx0b-001ae601.pphosted.com (mx0a-001ae601.pphosted.com [67.231.149.25]) by alsa0.perex.cz (Postfix) with ESMTP id 5C9F92667E7 for ; Wed, 18 Jan 2017 17:30:00 +0100 (CET) Received: from pps.filterd (m0077473.ppops.net [127.0.0.1]) by mx0a-001ae601.pphosted.com (8.16.0.20/8.16.0.20) with SMTP id v0IGTaTU027154; Wed, 18 Jan 2017 10:29:59 -0600 Authentication-Results: ppops.net; spf=none smtp.mailfrom=rf@opensource.wolfsonmicro.com Received: from mail2.cirrus.com (mail1.cirrus.com [141.131.3.20]) by mx0a-001ae601.pphosted.com with ESMTP id 27yj93xdmd-1; Wed, 18 Jan 2017 10:29:59 -0600 Received: from EX17.ad.cirrus.com (unknown [172.20.9.81]) by mail2.cirrus.com (Postfix) with ESMTP id AA8F06121ADE; Wed, 18 Jan 2017 10:29:58 -0600 (CST) Received: from imbe.wolfsonmicro.main (198.61.95.81) by EX17.ad.cirrus.com (172.20.9.81) with Microsoft SMTP Server id 14.3.301.0; Wed, 18 Jan 2017 16:29:57 +0000 Received: from rf-debian.wolfsonmicro.main ([172.22.20.124]) by imbe.wolfsonmicro.main (8.14.4/8.14.4) with ESMTP id v0IGTNfv026506; Wed, 18 Jan 2017 16:29:26 GMT From: Richard Fitzgerald To: Date: Wed, 18 Jan 2017 16:29:54 +0000 Message-ID: <1484756994-19679-2-git-send-email-rf@opensource.wolfsonmicro.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1484756994-19679-1-git-send-email-rf@opensource.wolfsonmicro.com> References: <1484756994-19679-1-git-send-email-rf@opensource.wolfsonmicro.com> MIME-Version: 1.0 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 priorityscore=1501 malwarescore=0 suspectscore=1 phishscore=0 bulkscore=0 spamscore=0 clxscore=1015 lowpriorityscore=0 impostorscore=0 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1612050000 definitions=main-1701180213 Cc: alsa-devel@alsa-project.org, patches@opensource.wolfsonmicro.com Subject: [alsa-devel] [PATCH 2/2] crecord: Add option to specify codec ID X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: alsa-devel-bounces@alsa-project.org Sender: alsa-devel-bounces@alsa-project.org X-Virus-Scanned: ClamAV using ClamSMTP This patch adds a -I command line option to set the codec ID, either from a defined set of string values or as a number. After discussion with Vinod it was agreed that we should only allow writing to a file if we support creating the correct container file format for that data. As we currently only have support for creating WAV files only PCM data can be written to a file. Other formats can be sent raw to stdout. Signed-off-by: Richard Fitzgerald --- src/utils/crecord.c | 99 ++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 87 insertions(+), 12 deletions(-) diff --git a/src/utils/crecord.c b/src/utils/crecord.c index 390fe45..1fd3698 100644 --- a/src/utils/crecord.c +++ b/src/utils/crecord.c @@ -83,6 +83,31 @@ static bool streamed; static const unsigned int DEFAULT_CHANNELS = 1; static const unsigned int DEFAULT_RATE = 44100; static const unsigned int DEFAULT_FORMAT = SNDRV_PCM_FORMAT_S16_LE; +static const unsigned int DEFAULT_CODEC_ID = SND_AUDIOCODEC_PCM; + +static const struct { + const char *name; + unsigned int id; +} codec_ids[] = { + { "PCM", SND_AUDIOCODEC_PCM }, + { "MP3", SND_AUDIOCODEC_MP3 }, + { "AMR", SND_AUDIOCODEC_AMR }, + { "AMRWB", SND_AUDIOCODEC_AMRWB }, + { "AMRWBPLUS", SND_AUDIOCODEC_AMRWBPLUS }, + { "AAC", SND_AUDIOCODEC_AAC }, + { "WMA", SND_AUDIOCODEC_WMA }, + { "REAL", SND_AUDIOCODEC_REAL }, + { "VORBIS", SND_AUDIOCODEC_VORBIS }, + { "FLAC", SND_AUDIOCODEC_FLAC }, + { "IEC61937", SND_AUDIOCODEC_IEC61937 }, + { "G723_1", SND_AUDIOCODEC_G723_1 }, + { "G729", SND_AUDIOCODEC_G729 }, +/* BESPOKE isn't defined on older kernels */ +#ifdef SND_AUDIOCODEC_BESPOKE + { "BESPOKE", SND_AUDIOCODEC_BESPOKE }, +#endif +}; +#define CREC_NUM_CODEC_IDS (sizeof(codec_ids) / sizeof(codec_ids[0])) struct riff_chunk { char desc[4]; @@ -151,9 +176,25 @@ static void size_wave_header(struct wave_header *header, uint32_t size) header->data.chunk.size = size; } +static const char *codec_name_from_id(unsigned int id) +{ + static char hexname[12]; + int i; + + for (i = 0; i < CREC_NUM_CODEC_IDS; ++i) { + if (codec_ids[i].id == id) + return codec_ids[i].name; + } + + snprintf(hexname, sizeof(hexname), "0x%x", id); + return hexname; /* a static is safe because we're single-threaded */ +} + static void usage(void) { - fprintf(stderr, "usage: crecord [OPTIONS] [filename]\n" + int i; + + fprintf(stderr, "usage: crecord [OPTIONS] [filename.wav]\n" "-c\tcard number\n" "-d\tdevice node\n" "-b\tbuffer size\n" @@ -163,13 +204,23 @@ static void usage(void) "-h\tPrints this help list\n\n" "-C\tSpecify the number of channels (default %u)\n" "-R\tSpecify the sample rate (default %u)\n" - "-F\tSpecify the format: S16_LE, S32_LE (default S16_LE)\n\n" - "If filename is not given the output is\n" - "written to stdout\n\n" + "-F\tSpecify the format: S16_LE, S32_LE (default S16_LE)\n" + "-I\tSpecify codec ID (default %s)\n\n" + "If filename.wav is not given the output is written to stdout\n" + "Only PCM data can be written to a WAV file.\n\n" "Example:\n" "\tcrecord -c 1 -d 2 test.wav\n" - "\tcrecord -f 5 test.wav\n", - DEFAULT_CHANNELS, DEFAULT_RATE); + "\tcrecord -f 5 test.wav\n" + "\tcrecord -I BESPOKE >raw.bin\n\n" + "Valid codec IDs:\n", + DEFAULT_CHANNELS, DEFAULT_RATE, + codec_name_from_id(DEFAULT_CODEC_ID)); + + for (i = 0; i < CREC_NUM_CODEC_IDS; ++i) + fprintf(stderr, "%s%c", codec_ids[i].name, + ((i + 1) % 8) ? ' ' : '\n'); + + fprintf(stderr, "\nor the value in decimal or hex\n"); exit(EXIT_FAILURE); } @@ -239,7 +290,8 @@ static int finish_record(void) static void capture_samples(char *name, unsigned int card, unsigned int device, unsigned long buffer_size, unsigned int frag, unsigned int length, unsigned int rate, - unsigned int channels, unsigned int format) + unsigned int channels, unsigned int format, + unsigned int codec_id) { struct compr_config config; struct snd_codec codec; @@ -289,7 +341,7 @@ static void capture_samples(char *name, unsigned int card, unsigned int device, memset(&codec, 0, sizeof(codec)); memset(&config, 0, sizeof(config)); - codec.id = SND_AUDIOCODEC_PCM; + codec.id = codec_id; codec.ch_in = channels; codec.ch_out = channels; codec.sample_rate = rate; @@ -409,10 +461,11 @@ int main(int argc, char **argv) { char *file; unsigned long buffer_size = 0; - int c; + int c, i; unsigned int card = 0, device = 0, frag = 0, length = 0; unsigned int rate = DEFAULT_RATE, channels = DEFAULT_CHANNELS; unsigned int format = DEFAULT_FORMAT; + unsigned int codec_id = DEFAULT_CODEC_ID; if (signal(SIGINT, sig_handler) == SIG_ERR) { fprintf(stderr, "Error registering signal handler\n"); @@ -423,7 +476,7 @@ int main(int argc, char **argv) usage(); verbose = 0; - while ((c = getopt(argc, argv, "hvl:R:C:F:b:f:c:d:")) != -1) { + while ((c = getopt(argc, argv, "hvl:R:C:F:I:b:f:c:d:")) != -1) { switch (c) { case 'h': usage(); @@ -463,6 +516,25 @@ int main(int argc, char **argv) usage(); } break; + case 'I': + if (optarg[0] == '0') { + codec_id = strtol(optarg, NULL, 0); + } else { + for (i = 0; i < CREC_NUM_CODEC_IDS; ++i) { + if (strcmp(optarg, + codec_ids[i].name) == 0) { + codec_id = codec_ids[i].id; + break; + } + } + + if (i == CREC_NUM_CODEC_IDS) { + fprintf(stderr, "Unrecognised ID: %s\n", + optarg); + usage(); + } + } + break; default: exit(EXIT_FAILURE); } @@ -472,14 +544,17 @@ int main(int argc, char **argv) file = NULL; finfo = fopen("/dev/null", "w"); streamed = true; - } else { + } else if (codec_id == SND_AUDIOCODEC_PCM) { file = argv[optind]; finfo = stdout; streamed = false; + } else { + fprintf(stderr, "ERROR: Only PCM can be written to a WAV file\n"); + exit(EXIT_FAILURE); } capture_samples(file, card, device, buffer_size, frag, length, - rate, channels, format); + rate, channels, format, codec_id); fprintf(finfo, "Finish capturing... Close Normally\n");