sox is probably the one linux program that continues to frustrate me. At the same time, I am awed by what it can do, and I'd like to get close to being fluent in it, if not mastering it.

Today, I've spent about 2 hours trying to get sox to read bytes from parec via a pipe.

The parec bytes are a pulseaudio "sink". In order to get them flowing through the pipe, I used this answer from askubuntu.

This is the command I've been using:

$ parec -d telephonControl.monitor | sox -b 16 -e signed -c 2 -r 44100 - -t pulse hmm.ogg silence 1 0.50 0.1% 1 2.0 0.1% :             newfile : restart

and this is the error I get:

sox FAIL formats: can't determine type of  `-'
write() failed: Broken pipe

What's more, oggenc parses them just fine:

parec -d telephonControl.monitor | oggenc -b 192 -o telephonControl.ogg --raw -
Encoding standard input to 
at approximate bitrate 192 kbps (VBR encoding enabled)

I have absolutely no idea how to make sox digest those bytes.

$ parec -d telephonControl.monitor >> somebytes

$ soxi somebytes
soxi FAIL formats: can't determine type of file `somebytes'

But I do know that they are raw audio, 16 bit signed little endian, 2 channel 44100kHz:

>>> list-sink-inputs
1 sink input(s) available.
    index: 17
        driver: <protocol-native.c>
        state: RUNNING
        sink: 2 <telephonControl>
        volume: 0: 100% 1: 100%
                0: 0.00 dB 1: 0.00 dB
                balance 0.00
        muted: no
        current latency: 92.86 ms
        requested latency: 23.20 ms
        sample spec: s16le 2ch 44100Hz
        channel map: front-left,front-right
        resample method: (null)
        module: 7
        client: 53 <ALSA plug-in>
                media.name = "ALSA Playback"
                application.name = "ALSA plug-in"
                native-protocol.peer = "UNIX socket client"
                native-protocol.version = "26"
                application.process.id = "3609"
                application.process.user = "alec"
                application.process.host = "ROOROO"
                window.x11.display = ":0"
                application.language = "en_GB.UTF-8"
                application.process.machine_id = "eec7c6ae60f90bb3921ad16d0000302d"
                application.process.session_id = "eec7c6ae60f90bb3921ad16d0000302d-1345384044.64188-1149507345"
                module-stream-restore.id = "sink-input-by-application-name:ALSA plug-in"

The -t option needs to come before the filename it applies to. Also, -t pulse means to read directly from (or write to) the PulseAudio daemon; it's not a file format as such. The type name for raw audio is raw.

Try this:

parec ... | sox -t raw -b 16 -e signed -c 2 -r 44100 - hmm.ogg ...

(where ... means to keep the same arguments you had before)

soxi can't identify the filetype because all it does is look at the header. Raw audio doesn't have a header for it to look at.

| improve this answer | |
  • 1
    so argument order is key when dealing with sox... i've definitely learned my lesson! – ixtmixilix Aug 20 '12 at 0:42
  • Many sox options (including -t) can apply to either the input or the output. The order of the arguments controls whether it's an input or output option. – cjm Aug 20 '12 at 2:52
  • I bumped into this post looking for playing direct from the stdin. Here is the command I used: play -t raw -b 16 -e signed -c 2 -r 44100 - – rodvlopes Jun 4 '16 at 3:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.