Question

I want to write audio data to stdout, preferably using libsndfile. When I output WAV to /dev/stdout I manage to write the header, but then I get an error

Error : could not open file : /dev/stdout
System error : Illegal seek.

I assume this is related to http://www.mega-nerd.com/libsndfile/FAQ.html#Q017, some file formats cannot be written without seeks. However, when I try to output SF_FORMAT_AU | SF_FORMAT_PCM_16 instead, I still get the same Illegal seek error.

Are there any audio file formats that can be written completely without seeking?

I'm using Linux.

EDIT: It might be obvious, but RAW format works (without seeking). Unfortunately I need a format that has meta information like sample rate.

Was it helpful?

Solution

You should finish reading that FAQ... the link you give us has all the answers.

However, there is at least one file format (AU) which is specifically designed to be written to a pipe.

So use AU instead of WAV.

Also make sure that you open the SNDFILE object with sf_open_fd, and not sf_open_virtual (or sf_open):

SNDFILE* sf_open_fd      (int fd, int mode, SF_INFO *sfinfo, int close_desc) ;
SNDFILE* sf_open_virtual (SF_VIRTUAL_IO *sfvirtual, int mode, SF_INFO *sfinfo,
                          void *user_data) ;

If you use sf_open_fd, then libsndfile will use fstat to determine whether the file descriptor is a pipe or a regular file. If you use sf_open_virtual or sf_open, it will assume that the file is seekable. This appears to be a flaw in libsndfile, but you should be using sf_open_fd anyway.

Footnote: Don't open /dev/stdout to get standard output; it is already open and there is no need to open it again. Use file descriptor STDOUT_FILENO.

OTHER TIPS

Ended outputting an "infinite" wav header, and then writing raw PCM data for as long as the audio lasts. Not really valid, but most players seem to understand anyway.

The wav header is here, in case anyone wants it: https://gist.github.com/1428176

You could write to a temp file (perhaps in /tmp), let the libsnd seek to modify the .wav(RIFF) header of the temp file, and then, after libsnd has closed the file, stream the temp file out to stdout.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top