1

I'm trying to use the sox terminal package in Linux to create a spectrogram png and display it in a GUI using Python. As I will need to use a sequence of images, I'm ultimately planning to implement this in a multiprocessing.Manager|Queue context.
The terminal command is:

:~$ sox sound.wav -n trim 42 6 rate 30k spectrogram -q 8 -r -l -m -o spectrogram.png

I can call this in a Python (3.4) script using

import subprocess
path= 'spectrogram.png'

process = 'sox sound.wav -n trim 42 6 rate 30k spectrogram -q 8 -r -l -m -o {}'.format(path)
subprocess.call(process, shell=True)

but (to speed things up a bit on a Raspberry Pi) I would rather not save to disk and then reload for the GUI.

My attempts using mkfifo e.g.:

import subprocess
import os    
path= '/tmp/spectrogram.png'
os.mkfifo(path)        
process = 'sox sound.wav -n trim 42 6 rate 30k spectrogram -q 8 -r -l -m -o {}'.format(path)
subprocess.call(process, shell=True)

have all failed (blocking, presumably cos I'm only using a single process?).

Examples I've found all concentrate on separate server/receiver processes and/or processing the terminal output (using, say stdout) not a file created by a command line process.

Not being experienced in Python (and a novice with the command line), I sense I'm "barking up the wrong tree" but don't I know where to look next!

cate
  • 600
  • 7
  • 15
  • I don't know anything about sox, but apparently there is a Python wrapper, [pysox](https://github.com/rabitt/pysox) - could that be helpful? – Daniel Roseman Jul 12 '17 at 13:25
  • @Daniel Roseman: thx Daniel, i'll take a look. If it's just a wrapper, however, it'll still only output to a disk file, I'd imagine – cate Jul 12 '17 at 14:07
  • Wait, do you want to have a file or not? What do you intend to do with the data exactly? – zwer Jul 12 '17 at 18:51
  • @zwer: Yes ~ in my `matplotlib`-based approach , I have been outputting the spectrograms to a string_rgb, avoiding using disk IO. My hope with the faster `sox` is that I could redirect the file output to a 'file' in memory and (perhaps in ignorance) thought that a pipe might be a solution. I have only tried named pipes so far; might anonymous pipes be any use? – cate Jul 12 '17 at 19:08
  • 1
    What version of `sox` do you use (`sox --version`)? If it's the latest ([`14.4.2`](https://sourceforge.net/p/sox/code/ci/45b161d73ec087a8e003747b1aed07cd33589bca/tree/ChangeLog)) you can redirect the spectrogram output to STDOUT and pick it up directly in Python without ever writing to a file. – zwer Jul 12 '17 at 19:27
  • @zwer : "What version of sox do you use": 14.4.1 - only installed two days ago. Looking at the `man` the only mention of `stdout` refers to _audio_ files. I see from your link the man for 14.4.2 refers to _image_ files too. Dunno why this 2015 change not available yet. – cate Jul 12 '17 at 19:35
  • 1
    `14.4.1` doesn't support writing spectrograms to STDOUT, so you'll need to save a file from it and then load it into Python - which is not all that bad, performance wise, mind you - after all, if you want to turn this into multiuprocessing code, it would probably be faster to just use the file system I/O than to pickle/unpickle the exchanged data (a default Python behavior when exchanging data between processes) – zwer Jul 12 '17 at 19:38
  • @zwer: yeah, point taken about pickling. I'll bash on with file IO approach and maybe try stdout as a comparison when 14.4.2 becomes available for Raspbian. I might know a bit more by then.... – cate Jul 12 '17 at 19:42
  • @zwer: just a quick last q as I've not used stdout; _would_ it involve pickling? I sorta assumed that like a file it wouldn't – cate Jul 12 '17 at 19:46
  • 1
    @cate - In a single-process setting, no pickling would be involved because you'd be reading directly from the STDOUT. But if your sub-processes were to do that and then send back the PNG data to the main process, then yes, diminishing any performance saving you might have gotten by avoiding file I/O. You may try speeding up your file I/O a bit, tho, by creating a ramdisk and making sox write to it and Python read from it. – zwer Jul 12 '17 at 19:52

0 Answers0