[FFmpeg-user] Convert audio to CSV

Oliver Fromme oliver at fromme.com
Sun Jun 30 15:27:06 EEST 2024


Michael Koch wrote:
 > is it possible to convert an audio waveform to a CSV list?
 > I want to insert 2048 samples of a waveform into the C source code for a 
 > microcontroller.

First convert the audio to raw PCM.  To do that, look at the output
of ''ffmpeg -codecs`` and search for the ones named ''pcm_*``.
There's a whole bunch of them -- take the one that fits your
application, according to sample size (typically 8 or 16 bit),
signedness (signed or unsigned), and byte order in the case of
16 bit or more (little-endian, big-endian).

For a small, space-constrained micro controller, 8-bit is probably
most appropriate (either signed or unsigned, depending on the
audio hardware).  The codec for 8-bit signed would be ''pcm_s8``.

In order to write the result as a raw PCM file without header,
use the ''s8`` format (see the list with ''ffmpeg -formats``).
The format must match the codec.

So, the ffmpeg command line will look something like this:

ffmpeg -i INPUT_FILE -map 0:a:0 -ac 1 -c:a pcm_s8 -f s8 wave.pcm

That will read the file INPUT_FILE, take the first audio stream
(-map 0:a:0), convert to mono (-ac 1), and write it as signed
8-bit raw PCM data to the file wave.pcm.

Depending on your source file, you might also have to change
the sampling rate (e.g. from 44100 Hz to 22050 Hz or whatever
you need).  ''-ar 22050`` will do that.  You might also have to
cut the part that you're interested in if the whole file is more
than 2048 samples, as you mentioned:  Use -ss to seek to a
specific position, and ''-fs 2048`` to limit the output file
size to 2048 bytes.  See the ffmpeg manual page for details.
The output file may actually become slightly larger than 2048
bytes; in that case truncate the file afterwards (on Linux and
BSD systems you can use the command ''truncate -s2048 wave.pcm``
to do that).

Finally, to include the data in your C source file, you'll have
to convert the binary data to a hex dump or decoimal dump.
Ffmpeg doesn't do that, so you'll have to do it with a tool of
your operating system.  For example, BSD and Linux systems offer
various command line tools for that purpose, called hexdump, hd,
or od.  Consult the documentation (manual pages).

For example, the following will produce a comma-separated list
of signed decimal bytes:

od -An -vt dC wave.pcm | sed 's/\([0-9]\)\([^0-9]\)/\1,\2/g;s/$/,/'

That one seems complicated, but it has the advantage that it
should work on any POSIX-compatible system (the hexdump utility,
for example, is non-standard and has different syntax on different
systems).  The ''od`` command above produces a table of signed
decimal bytes (''signed char`` in C speak).  The ''sed`` command
takes that output and inserts commas between columns, and also
appends commas at the end of each line.

The result can be taken directly into your source code, just
prepend an assignment in front of the first line, like:

    const my_wave = (

and remove the last comma at the end of the last line of data,
and append ``);'' to finish the statement.

Best regards
Oliver


More information about the ffmpeg-user mailing list