Jyri Sarha [Mon, 30 Mar 2026 20:45:38 +0000 (23:45 +0300)]
utils: add sofprobeclient binary
Add sofprobeclient, a SOF probe client for compressed audio
capture based on crecord. Built from its own source file with
the same libtinycompress linkage as cplay and crecord.
At this phase the sofprobeclient.c is almost exact copy of
crecord.c. Only the reference to the command name have been updated
from "crecord" to "sofprobeclient".
This is a staring point for SOF probe debugging tool that uses
compressed audio capture device for routing logs and audio form
defined probe points out of the DSP subsystem.
Closes: https://github.com/alsa-project/tinycompress/pull/35 Signed-off-by: Jyri Sarha <jyri.sarha@linux.intel.com> Signed-off-by: Jaroslav Kysela <perex@perex.cz>
Seppo Ingalsuo [Wed, 11 Mar 2026 10:27:37 +0000 (12:27 +0200)]
Utils: cplay: Fix WAV header parsing for multi-channel (5.1/7.1) formats
Multi-channel WAV files (>2 channels) use WAVE_FORMAT_EXTENSIBLE
(type 0xFFFE) with a larger fmt chunk that includes a channel mask
and subformat GUID. The existing parser only handled basic PCM
(type 0x0001), causing several issues with 5.1 (6ch) and 7.1 (8ch)
content:
- The fixed-size fread of struct wave_header (44 bytes) misaligned
the data chunk read when the fmt chunk was larger than 16 bytes,
resulting in audio data being read from the wrong file offset.
- No chunk scanning was performed, so intermediate chunks (fact,
LIST, PEAK) between fmt and data caused parse failures.
- The WAV channel mask (speaker positions FL, FR, FC, LFE, BL, BR,
SL, SR) was never extracted, so firmware received ch_mode=0 and
could not determine the correct channel-to-speaker routing.
Add parse_wave_file() that properly scans chunks, handles both basic
PCM and WAVE_FORMAT_EXTENSIBLE formats, extracts the channel mask,
and positions the file pointer at the start of audio data. For basic
PCM files with >2 channels, a standard default channel mask is
generated per the Microsoft WAV specification.
The channel mask is passed to firmware via snd_codec.ch_mode so it
can correctly map channels to speaker positions. Also add 24-bit
sample format support (SNDRV_PCM_FORMAT_S24_LE).
Closes: https://github.com/alsa-project/tinycompress/pull/32 Signed-off-by: Seppo Ingalsuo <seppo.ingalsuo@linux.intel.com> Signed-off-by: Jaroslav Kysela <perex@perex.cz>
Peter Ujfalusi [Wed, 11 Mar 2026 13:55:30 +0000 (15:55 +0200)]
fcplay: Add restart continuous playback strategy
The restart mode can be requested with -p2 which will result an
open->config->start->drain->close sequence for each of the files.
Closes: https://github.com/alsa-project/tinycompress/pull/33 Signed-off-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com> Signed-off-by: Jaroslav Kysela <perex@perex.cz>
Peter Ujfalusi [Wed, 11 Mar 2026 13:43:29 +0000 (15:43 +0200)]
fcplay: Introduce new continuous_playback_mode to replace the gapless flag
Add continuous_playback_mode enum to allow expanding the strategies used
for continuous compressed playback (when more than one file is played in a
sequence).
Currently fcplay supports two modes:
0 (w/o -g 1) when each file is just sent over the compress buffer without
any action taken in between the files - NOP mode
1 (w/ -g 1) gapless mode, using metadata, neext_track and partial drain -
GAPLESS mode
No functional change expected.
Closes: https://github.com/alsa-project/tinycompress/pull/33 Signed-off-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com> Signed-off-by: Jaroslav Kysela <perex@perex.cz>
Peter Ujfalusi [Wed, 11 Mar 2026 11:46:38 +0000 (13:46 +0200)]
fcplay: Create helper function to open and start the compress device
No functional change, just to prepare to support different continuous
playback strategies.
Closes: https://github.com/alsa-project/tinycompress/pull/33 Signed-off-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com> Signed-off-by: Jaroslav Kysela <perex@perex.cz>
Peter Ujfalusi [Wed, 11 Mar 2026 06:57:34 +0000 (08:57 +0200)]
fcplay: Correct metadata.next_track sequence for gapless playback
The kernel demands the metadata to be set before the next_track is
signaled (since 2013).
Calling next_track before set metadata will case the next_track to be
'lost' in core's snd_compr_next_track().
Reverse the call order of next_track and set_metadata to fix this.
Fixes: 40603c037c8d ("fcplay: Modify play_samples func to support gapless playback.") Closes: https://github.com/alsa-project/tinycompress/pull/33 Signed-off-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com> Signed-off-by: Jaroslav Kysela <perex@perex.cz>
Peter Ujfalusi [Thu, 12 Mar 2026 11:31:43 +0000 (13:31 +0200)]
fcplay: Decode the AAC header to set correct codec->format value
Set the codec->format for AAC based on the information from the header.
Closes: https://github.com/alsa-project/tinycompress/pull/34 Signed-off-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com> Signed-off-by: Jaroslav Kysela <perex@perex.cz>
Jaroslav Kysela [Wed, 21 Jan 2026 10:53:46 +0000 (11:53 +0100)]
compress_ops: remove get_tstamp64 callback
It is not required to polute ops with two versions
of similar callbacks when we introduced V2 ops. Handle the
wrapping in the top level (compress_get_tstamp function).
Closes: https://github.com/alsa-project/tinycompress/pull/31 Signed-off-by: Jaroslav Kysela <perex@perex.cz>
Jaroslav Kysela [Wed, 21 Jan 2026 10:31:55 +0000 (11:31 +0100)]
compress_ops: add magic and look for compress_plugin_mops symbol
We need more validation of passed ops structure to allow
further API changes in future.
This change looks for compress_plugin_mops symbol in the
dynamic plugin library to make sure that the new magic
and new get_tstamp64 members are handled correctly.
src: lib: Add API to set codec parameters for next track
For gapless playback usecase where each track differs in encoding,
new codec parameters that need to be propagated to kernel is done
via compress_set_codec_params()
Vinod Koul [Thu, 13 Oct 2022 12:45:54 +0000 (18:15 +0530)]
cplay: add parentheses around comparison in operand of ‘&’
We get a warning:
cplay.c: In function ‘find_adts_header’:
cplay.c:259:41: warning: suggest parentheses around comparison in operand of ‘&’ [-Wparentheses]
259 | if ((buf[0] != 0xff) || (buf[1] & 0xf0 != 0xf0))
Vinod Koul [Thu, 13 Oct 2022 12:19:57 +0000 (17:49 +0530)]
cplay: remove set but not used warnings
cplay.c: In function ‘find_adif_header’:
cplay.c:367:13: warning: variable ‘object_type’ set but not used [-Wunused-but-set-variable]
367 | int object_type;
| ^~~~~~~~~~~
cplay.c:366:13: warning: variable ‘bitrate’ set but not used [-Wunused-but-set-variable]
366 | int bitrate;
| ^~~~~~~
cplay.c:91:27: warning: ‘DEFAULT_CODEC_ID’ defined but not used [-Wunused-const-variable=]
91 | static const unsigned int DEFAULT_CODEC_ID = SND_AUDIOCODEC_PCM;
| ^~~~~~~~~~~~~~~~
While at it, cleanup the code a bit as well removing now redundant
braces around if-else
This patch will allow playing MP3 files containing ID3v2
tag at the beginning of the file.
This is done simply by parsing the ID3v2 header, extracting
the header size and seeking to that position (+10 bytes
from the header size which is not included in the 'header
size' field of the ID3v2 header)
We want to be able to pause and resume the stream
just like the ALSA utilitary aplay does.
In order to do so, we first need to mark the read operations
on stdin as nonblocking and then enable the noncanonical mode
for the terminal. What this does is it makes the read operations
nonblocking and it makes the input available immediately.
After doing so, we can check if we receive a SPACE or ENTER
character from user and do pause/resume depending on current
stream state (and by this I mean if the stream is currently
paused and we receive a SPACE or ENTER then we resume it
and vice-versa)
utils: cplay: Reset file cursor after MP3 header parse
We need to reset the file cursor to the beginning of the file.
Initially, the program would simply get stuck polling the
compress fd. This was probably because of the fact that the
codec would hang because of the fact that it was expecting
to receive the MP3 data along with its associated MP3 header.
This was not the case for the first (header, data) pair because,
after parsing the first header, the file cursor would point
at the beginning of the data region.
By resetting the file cursor to the beginning of the file,
the codec will receive all the (header, data) pairs it
actually expects.
Suggested-by: Shengjiu Wang <shengjiu.wang@nxp.com> Signed-off-by: Laurentiu Mihalcea <laurentiu.mihalcea@nxp.com>
Daniel Baluta [Thu, 7 Jan 2021 21:01:06 +0000 (23:01 +0200)]
cplay: Add suport for PCM audio codec
Make use of newly added parse_wave_header function in order
to discover PCM codec properties.
PCM with tinycompress interface is very useful for testing
new compress API implementations and can be enabled using
--enable-pcm option at configuration time.
e.g:
- ./gitcompile --enable-pcm
Signed-off-by: Daniel Baluta <daniel.baluta@nxp.com>
Daniel Baluta [Thu, 7 Jan 2021 20:57:14 +0000 (22:57 +0200)]
wave: Introduce parse_wave header
This parses a canonical WAVE header and fills in
informationlike channels, rate and format.
In tinycompress, we use canonical WAVE format described here:
http://soundfile.sapp.org/doc/WaveFormat/
A WAVE file is often just a RIFF file with a single "WAVE" chunk which
consists of two sub-chunks -- a "fmt " chunk specifying the data format
and a "data" chunk containing the actual sample data.
Signed-off-by: Daniel Baluta <daniel.baluta@nxp.com>
Add compress_open_by_name() and is_codec_supported_by_name()
to support plugins. Format of name is 'hw:<card>,<device>'
for hw compress nodes and '<plugin_name>:<custom_data>'
for virtual compress nodes. It dynamically loads the plugin
library whose name is libtinycompress_module_<plugin_name>.so.
Plugin library needs to expose compress_plugin_ops.
Default path of plugin lib is /usr/lib/tinycompress-lib/ and it
can be updated by defining TINYCOMPRESS_PLUGIN_DIR in makefile.
Vinod Koul [Thu, 5 Dec 2019 07:57:28 +0000 (13:27 +0530)]
fcplay: initial addition
This tool was forked from tinycompress cplay. The fork was required due
to this linking against libavcodec which is GPL. This uses libav APIs to
parse the compressed files and send the audio stream to compressed
device using tinycompress APIs
Right now it supports only playback on MP3 (no problems now not finding
sync word) and flac files.
Charles Keepax [Thu, 8 Nov 2018 17:12:32 +0000 (17:12 +0000)]
tinycompress: Update headers to include AUDIOCODEC_BESPOKE
commit dbb6b94339e8 ("ALSA: compress: Add SND_AUDIOCODEC_BESPOKE") added
an additional CODEC type for bespoke CODECs. Update the local headers to
include this.
Reported-by: Andrew Ford <andrew.ford@cirrus.com> Signed-off-by: Charles Keepax <ckeepax@opensource.cirrus.com> Signed-off-by: Vinod Koul <vkoul@kernel.org>
We get a warning in crecord for incorrect print specifier, fix it by using
right one %u for unsigned int
crecord.c:380:17: warning: format ‘%lu’ expects argument of type ‘long unsigned int’, but argument 6 has type ‘unsigned int’ [-Wformat=]
fprintf(finfo, "Recording file %s On Card %u device %u, with buffer of %lu bytes\n",
We get a warning in cplay for incorrect print specifier, fix it by using
right one %ld for long unsigned int.
cplay.c:327:19: warning: format ‘%d’ expects argument of type ‘int’, but argument 3 has type ‘long unsigned int’ [-Wformat=]
fprintf(stderr, "codec ID %d is not supported\n", codec_id);
Charles Keepax [Fri, 13 Apr 2018 11:58:59 +0000 (12:58 +0100)]
crecord: Use whole buffer requested by user
Currently, crecord will only actually use 1 fragment worth of its
internal buffer no matter what the user requests. Correct this so that
the whole buffer requested by the user is used for copying data.
Signed-off-by: Charles Keepax <ckeepax@opensource.cirrus.com> Signed-off-by: Vinod Koul <vinod.koul@intel.com>
Katsuhiro Suzuki [Tue, 23 Jan 2018 02:33:11 +0000 (11:33 +0900)]
cplay: fix size and nmemb of mp3 header of fread
This patch swaps 'size' and 'nmemb' arguments of fread.
The fread returns always 1 (because 'nmemb' is 1) so checking
the return value is always failure.
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 <rf@opensource.wolfsonmicro.com> Signed-off-by: Vinod Koul <vinod.koul@intel.com>
- Incorrect indenting of arguments to capture_samples()
- Wrap long line in capture_samples()
- Added a blank line in main() for readability
- Deleted extra trailing blank line at end of file
Signed-off-by: Richard Fitzgerald <rf@opensource.wolfsonmicro.com> Signed-off-by: Vinod Koul <vinod.koul@intel.com>
Vinod Koul [Sat, 9 Jan 2016 08:12:46 +0000 (13:42 +0530)]
tinycompress: crec: make functions static
Sparse rightly complains some functions should be static so make them static
crec.c:113:26: warning: symbol 'blank_wave_header' was not declared. Should it be static?
crec.c:239:6: warning: symbol 'capture_samples' was not declared. Should it be static?
Vinod Koul [Sat, 9 Jan 2016 08:12:46 +0000 (13:42 +0530)]
tinycompress: cplay: make functions static
Sparse rightly complains some functions should be static so make them static
cplay.c:100:5: warning: symbol 'parse_mp3_header' was not declared. Should it be static?
cplay.c:129:5: warning: symbol 'check_codec_format_supported' was not declared. Should it be static?
../../include/tinycompress/tinymp3.h:66:11: warning: symbol 'mp3_sample_rates' was not declared. Should it be static?
../../include/tinycompress/tinymp3.h:72:11: warning: symbol 'mp3_bit_rates' was not declared. Should it be static?