10

for a single .mp3, I can convert it to wav using

sox ./input/filename.mp3 ./output/filename.wav

I tried:

#!/bin/bash
for i in  $(ls *mp3)
do
    sox -t wav $i waves/$(basename $i)
done

But it throws the following error:

sox FAIL formats: can't open input file `filename.mp3': WAVE: RIFF header not found

How would I run this sox conversion over all mp3 files in the input folder and save the generated wav's to the output folder?

PS : I don't know why it shows the file enclosed between a back quote ( ` ) and an apostrophe '

`filename.mp3'

I played all the mp3's and they work perfectly file.

ilkkachu
  • 138,973
kRazzy R
  • 269

3 Answers3

12

It sounds like you're running into a problem with spaces in the filename. If you have a file named "My Greatest Hits.mp3", your command will try to convert the three different files named "My", "Greatest", and "Hits.mp3". Instead of using the "$()" syntax, just use "*.mp3" in the for line, and make sure to quote the file names in the sox command.

In addition, the basename command doesn't remove the file extension, just any folder names. So this command will create a bunch of WAV files with a ".mp3" extension. Adding "-s .mp3" to the command tells basename to strip the extension, and then put ".wav" on the end adds the correct extension.

Put it all together, and you have this:

for i in *.mp3
do
    sox "$i" "waves/$(basename -s .mp3 "$i").wav"
done
HiddenWindshield
  • 607
  • 5
  • 12
2

First, don't use ls like that, it doesn't actually do anything, since it's the shell that actually generates the filenames in the glob *mp3 anyway. Plus it breaks if any of your files have whitespace in their names.

As for the error, I think sox here tries to interpret the MP3 file as a wav, since you gave the -t wav flag. I think you could do without it, as you did in the single-file case. You just need to change the extension on the output file name too. basename can remove the suffix too, if you tell it what to remove.

#!/bin/bash
for i in *.mp3
do
    sox "$i" "waves/$(basename "$i" .mp3).wav"
done

(The backtick-apostrophe is an ancient custom of `quoting' the file name. I the backtick is supposed to look like the left-side quotation mark, the one that looks like a rotated comma (see examples on Wikipedia). But technically, it's wrong, and it looks awful in most current fonts.)

ilkkachu
  • 138,973
  • thanks for the answer. in case I want it to take an input directory from a particular folder , how would I do that ex ./input/media – kRazzy R Feb 20 '18 at 23:42
  • 1
    @kRazzyR, just put the directory in the pattern: for i in /some/path/*.mp3 ... and fix the destination directory as required. basename removes the directory from the file name anyway, so that part's not a problem. – ilkkachu Feb 21 '18 at 08:51
0

Clearly, sox is saying it can't process the mp3 format file. I would be very interested in getting the output on your system for:

sox ./input/filename.mp3 ./output/filename.wav

Because it seems your sox cannot process mp3 in general. Yes, sox can be recompiled to handle mp3, but your error message indicates it is reading the file, but it's expecting a wav: WAVE: RIFF header not found.

The other comments about issues with spaces still apply in general, but the file filename.mp3 doesn't have spaces; it's an mp3.

PePa
  • 91