diff options
Diffstat (limited to 'recipes-multimedia/tinycompress/tinycompress/0002-cplay-Support-wave-file.patch')
-rwxr-xr-x | recipes-multimedia/tinycompress/tinycompress/0002-cplay-Support-wave-file.patch | 215 |
1 files changed, 215 insertions, 0 deletions
diff --git a/recipes-multimedia/tinycompress/tinycompress/0002-cplay-Support-wave-file.patch b/recipes-multimedia/tinycompress/tinycompress/0002-cplay-Support-wave-file.patch new file mode 100755 index 00000000..79544711 --- /dev/null +++ b/recipes-multimedia/tinycompress/tinycompress/0002-cplay-Support-wave-file.patch @@ -0,0 +1,215 @@ +From 4d4bc0a958fe254531920095fbabc241aad88113 Mon Sep 17 00:00:00 2001 +From: Shengjiu Wang <shengjiu.wang@nxp.com> +Date: Tue, 28 Jul 2020 13:00:36 +0800 +Subject: [PATCH] cplay: Support wave file + +The supported format is mono/stereo, S16_LE/S32_LE, 8kHz-192kHz. +Command is: +cplay -c x -I PCM test.wav + +Upstream-Status: Inappropriate [i.MX specific] +Signed-off-by: Shengjiu Wang <shengjiu.wang@nxp.com> +--- + include/tinycompress/wave_formats.h | 51 +++++++++++++ + src/utils/cplay.c | 107 ++++++++++++++++++++++++++++ + 2 files changed, 158 insertions(+) + create mode 100644 include/tinycompress/wave_formats.h + +--- /dev/null ++++ b/include/tinycompress/wave_formats.h +@@ -0,0 +1,53 @@ ++#ifndef WAVE_FORMATS_H ++#define WAVE_FORMATS_H 1 ++ ++#include <sys/types.h> ++ ++#define COMPOSE_ID(a,b,c,d) ((a) | ((b)<<8) | ((c)<<16) | ((d)<<24)) ++ ++#define WAV_RIFF COMPOSE_ID('R','I','F','F') ++#define WAV_RIFX COMPOSE_ID('R','I','F','X') ++#define WAV_WAVE COMPOSE_ID('W','A','V','E') ++#define WAV_FMT COMPOSE_ID('f','m','t',' ') ++#define WAV_DATA COMPOSE_ID('d','a','t','a') ++ ++/* WAVE fmt block constants from Microsoft mmreg.h header */ ++#define WAV_FMT_PCM 0x0001 ++#define WAV_FMT_IEEE_FLOAT 0x0003 ++#define WAV_FMT_DOLBY_AC3_SPDIF 0x0092 ++#define WAV_FMT_EXTENSIBLE 0xfffe ++ ++/* Used with WAV_FMT_EXTENSIBLE format */ ++#define WAV_GUID_TAG "\x00\x00\x00\x00\x10\x00\x80\x00\x00\xAA\x00\x38\x9B\x71" ++ ++typedef struct { ++ u_int magic; /* 'RIFF' */ ++ u_int length; /* filelen */ ++ u_int type; /* 'WAVE' */ ++} WaveHeader; ++ ++typedef struct { ++ u_short format; /* see WAV_FMT_* */ ++ u_short channels; ++ u_int sample_fq; /* frequence of sample */ ++ u_int byte_p_sec; ++ u_short byte_p_spl; /* samplesize; 1 or 2 bytes */ ++ u_short bit_p_spl; /* 8, 12 or 16 bit */ ++} WaveFmtBody; ++ ++typedef struct { ++ WaveFmtBody format; ++ u_short ext_size; ++ u_short bit_p_spl; ++ u_int channel_mask; ++ u_short guid_format; /* WAV_FMT_* */ ++ u_char guid_tag[14]; /* WAV_GUID_TAG */ ++} WaveFmtExtensibleBody; ++ ++typedef struct { ++ u_int type; /* 'data' */ ++ u_int length; /* samplecount */ ++} WaveChunkHeader; ++ ++ ++#endif /* FORMATS */ +--- a/src/utils/cplay.c ++++ b/src/utils/cplay.c +@@ -1,4 +1,6 @@ + /* ++ * Copyright 2020 NXP ++ * + * This file is provided under a dual BSD/LGPLv2.1 license. When using or + * redistributing this file, you may do so under either license. + * +@@ -73,6 +75,8 @@ + #include "tinycompress/tinycompress.h" + #include "tinycompress/tinymp3.h" + #include "tinycompress/id3_tag_decode.h" ++#include "tinycompress/wave_formats.h" ++#include <alsa/asoundlib.h> + + static int verbose; + static const unsigned int DEFAULT_CODEC_ID = SND_AUDIOCODEC_PCM; +@@ -166,6 +170,77 @@ static int parse_mp3_header(struct mp3_h + return 0; + } + ++static int parse_wav_header(FILE *file, unsigned int *num_channels, unsigned int *sample_rate, ++ unsigned int *format) { ++ WaveHeader wave_header; ++ WaveChunkHeader chunk_header; ++ WaveFmtBody fmt_body; ++ int more_chunks = 1; ++ ++ fread(&wave_header, sizeof(WaveHeader), 1, file); ++ if ((wave_header.magic != WAV_RIFF) || ++ (wave_header.type != WAV_WAVE)) { ++ fprintf(stderr, "Error: it is not a riff/wave file\n"); ++ return -1; ++ } ++ ++ do { ++ fread(&chunk_header, sizeof(WaveChunkHeader), 1, file); ++ switch (chunk_header.type) { ++ case WAV_FMT: ++ fread(&fmt_body, sizeof(WaveFmtBody), 1, file); ++ /* If the format header is larger, skip the rest */ ++ if (chunk_header.length > sizeof(WaveFmtBody)) ++ fseek(file, chunk_header.length - sizeof(WaveFmtBody), SEEK_CUR); ++ ++ *num_channels = fmt_body.channels; ++ *sample_rate = fmt_body.sample_fq; ++ ++ switch (fmt_body.bit_p_spl) { ++ case 8: ++ *format = SND_PCM_FORMAT_U8; ++ break; ++ case 16: ++ *format = SND_PCM_FORMAT_S16_LE; ++ break; ++ case 24: ++ switch (fmt_body.byte_p_spl / fmt_body.channels) { ++ case 3: ++ *format = SND_PCM_FORMAT_S24_3LE; ++ break; ++ case 4: ++ *format = SND_PCM_FORMAT_S24_LE; ++ break; ++ default: ++ fprintf(stderr, "format error\n"); ++ return -1; ++ } ++ break; ++ case 32: ++ if (fmt_body.format == WAV_FMT_PCM) { ++ *format = SND_PCM_FORMAT_S32_LE; ++ } else if (fmt_body.format == WAV_FMT_IEEE_FLOAT) { ++ *format = SND_PCM_FORMAT_FLOAT_LE; ++ } ++ break; ++ default: ++ fprintf(stderr, "format error\n"); ++ return -1; ++ } ++ break; ++ case WAV_DATA: ++ /* Stop looking for chunks */ ++ more_chunks = 0; ++ break; ++ default: ++ /* Unknown chunk, skip bytes */ ++ fseek(file, chunk_header.length, SEEK_CUR); ++ } ++ } while (more_chunks); ++ ++ return 0; ++} ++ + static int print_time(struct compress *compress) + { + unsigned int avail; +@@ -385,6 +460,35 @@ void get_codec_iec(FILE *file, struct co + codec->format = 0; + } + ++void get_codec_pcm(FILE *file, struct compr_config *config, ++ struct snd_codec *codec) ++{ ++ unsigned int channels, rate, format; ++ ++ if (parse_wav_header(file, &channels, &rate, &format) == -1) { ++ fclose(file); ++ exit(EXIT_FAILURE); ++ } ++ ++ if (channels > 2 || (format != SND_PCM_FORMAT_S16_LE && format != SND_PCM_FORMAT_S32_LE) || ++ rate > 192000) { ++ fprintf(stderr, "unsupported wave file\n"); ++ fclose(file); ++ exit(EXIT_FAILURE); ++ } ++ ++ codec->id = SND_AUDIOCODEC_PCM; ++ codec->ch_in = channels; ++ codec->ch_out = channels; ++ codec->sample_rate = rate; ++ codec->bit_rate = 0; ++ codec->rate_control = 0; ++ codec->profile = SND_AUDIOPROFILE_PCM; ++ codec->level = 0; ++ codec->ch_mode = 0; ++ codec->format = format; ++} ++ + void play_samples(char *name, unsigned int card, unsigned int device, + unsigned long buffer_size, unsigned int frag, + unsigned long codec_id) +@@ -411,6 +515,9 @@ void play_samples(char *name, unsigned i + case SND_AUDIOCODEC_IEC61937: + get_codec_iec(file, &config, &codec); + break; ++ case SND_AUDIOCODEC_PCM: ++ get_codec_pcm(file, &config, &codec); ++ break; + default: + fprintf(stderr, "codec ID %ld is not supported\n", codec_id); + exit(EXIT_FAILURE); |