Sox batch process under Debian - linux

I want to resample a bunch of wav files that I got on a folder.
My script is this:
for f in *.wav; do sox “$f” -r 48000 “${f%%%.wav}.wav”; done
The console give me this error: "sox FAIL formats: can't open input file `“90.wav”': No such file or directory" and so on with the 300 files that are placed on that folder.
How can I batch processing right this files? Why is it giving me this error?
Thanks a lot!
Solution:
for i in *wav; do echo $i; sox $i -r 48000 ${i%%.wav}r.wav; done

Summary: It is the quote symbols
The problem is with the double-quotes:
for f in *.wav; do sox “$f” -r 48000 “${f%%%.wav}.wav”; done
The double-quotes above are non-standard. For them to be properly processed by the shell, the standard ASCII quote symbol must be used:
for f in ./*.wav; do sox "$f" -r 48000 "${f%%%.wav}.wav"; done
As an aside, note that ${f%%%.wav} removes any occurrences of %.wav from the end of the input file name. ${f%%%.wav}.wav adds one .wav back on to the end after removing any %.wav suffixes. You likely want something else here.
Verification
Using the bad quote characters, as per the question, observe the error message:
$ for f in *.wav; do sox “$f” -r 48000 “${f%%%.wav}.wav”; done
sox FAIL formats: can't open input file `“90.wav”': No such file or directory
Note the file name in the error message is shown with two-sets of quotes around the file name. This is what you saw as per the error message that in the question. The outer single-quotes are supplied by sox. The inner double-quotes are the funny quote characters provided on the command line. Because they are non-standard characters, the shell left them in place and passed them to the sox command.
While the file 90.wav exists, no file by the name of “90.wav” exists. Hence, the error.
Conclusion
Stick to standard ASCII characters for shell commands.
This issue can easily happen if the shell commands are typed in using a fancy word-processing editor that substitutes in typographically-pretty but non-standard characters. As tripleee points out, it can also happen when copying-and-pasting from the websites with inappropriate typographical styling.

Related

Is it possible to display a file's contents and delete that file in the same command?

I'm trying to display the output of an AWS lambda that is being captured in a temporary text file, and I want to remove that file as I display its contents. Right now I'm doing:
... && cat output.json && rm output.json
Is there a clever way to combine those last two commands into one command? My goal is to make the full combined command string as short as possible.
For cases where
it is possible to control the name of the temporary text file.
If file is not used by other code
Possible to pass "/dev/stdout" as the.name of the output
Regarding portability: see stack exchange how portable ... /dev/stdout
POSIX 7 says they are extensions.
Base Definitions,
Section 2.1.1 Requirements:
The system may provide non-standard extensions. These are features not required by POSIX.1-2008 and may include, but are not limited to:
[...]
• Additional character special files with special properties (for example,  /dev/stdin, /dev/stdout,  and  /dev/stderr)
Using the mandatory supported /dev/tty will force output into “current” terminal, making it impossible to pipe the output of the whole command into different program (or log file), or to use the program when there is no connected terminals (cron job, or other automation tools)
No, you cannot easily remove the lines of a file while displaying them. It would be highly inefficient as it would require removing characters from the beginning of a file each time you read a line. Current filesystems are pretty good at truncating lines at the end of a file, but not at the beginning.
A simple but extremely slow method would look like this:
while [ -s output.json ]
do
head -1 output.json
sed -i 1d output.json
done
While this algorithm is plain and simple, you should know that each time you remove the first line with sed -i 1d it will copy the whole content of the file but the first line into a temporary file, resulting in approximately 0.5*n² lines written in total (where n is the number of lines in your file).
In theory you could avoid this by do something like that:
while [ -s output.json ]
do
line=$(head -1 output.json)
printf -- '%s\n' "$line"
fallocate -c -o 0 -l $((${#len}+1)) output.json
done
But this does not account for variable newline characters (namely DOS-formatted newlines) and fallocate does not always work on xfs, among other issues.
Since you are trying to consume a file alongside its creation without leaving a trace of its existence on disk, you are essentially asking for a pipe functionality. In my opinion you should look into how your output.json file is produced and hopefully you can pipe it to a script of your own.

ffmpeg being inprecise when trimming mp3 files

I want to use ffmpeg to trim some mp3s without re-encoding. The command I used was
ffmpeg -i "inputfile.mp3" -t 00:00:12.414 -c copy out.mp3
However, out.mp3 has a length of 12.460s, and when I load the file in Audacity I can see that it was cut at the wrong spot, and not at 12.414s.
Why is this? I googled a bit and tried some other commands like ffmpeg -i "inputfile.mp3" -ss 0 -to 00:00:12.414 -c copy out.mp3 (which interestingly results in a different length of 12.434s) but could never get the milliseconds to be cut right.
PS. I wasn't sure whether SO was the right place to ask since it isn't technically programming related, however most of the stuff I found on ffmpeg for trimming audio files were stackoverflow questions, e. g. ffmpeg trimming videos with millisecond precision
You can't trim MP3 (nor most lossy codec output) with that level of precision. An MP3 frame or so of padding is added during encoding. (See also: https://wiki.hydrogenaud.io/index.php?title=Gapless, and all the hacks required to make this work.)
If you need precision timing, use something uncompressed like PCM in WAV, or a lossless compression like FLAC.
On Linux you can use mp3splt:
mp3splt -f mp3file.mp3 from to -o output file format
Example:
mp3splt -f "/home/audio folder/test.mp3" 0.11.89 3.25.48 -o #f_trimmed
this will create a "/home/audio folder/test_trimmed.mp3"
For more info to the parameters, check the mp3splt man page here
On Windows you can use mp3DirectCut
mp3DirectCut has a GUI, but it also have command line support

Convert (numerically ordered) bitmap files to video file using avconv

I am attempting to convert a directory full of .bmp files into a .mp4 file (or similar format).
The bitmap files have the following name scheme:
output_N_1024.bmp
Where N is an integer in the range 0 to 1023. (No zero padding / fixed width.)
The command I am using is:
avconv -r 25 -i output_{0..1023}_1024.bmp outputfile.mp4
This appears to run okay, and takes about a minute to convert all 1024, 1024 by 1024 resolution - (confusing?) bitmap images into a new file, outputfile.mp4.
However, when I attempt to open this file with VLC, a black window briefly flashes up and then closes. VLC then goes back to its mode where it waits for you to tell it which file to open next. No error or warning messages appear from VLC, which seems kind of strange since it seems to be refusing to play.
What can I do to fix this? Perhaps my converting command is incorrect?
The problem most likely is that you haven't actually passed the command to encode these files to avconv. This has happened because your shell has expanded the filenames already.
The command i have just managed to get to work on my machine is:
avconv -r 2 -i "%d.bmp" -s 600x400 -an out.ogv
Also for whatever reason it didn't want to work without explicitely giving it the size, but i don't think this is your problem.
In here quotes tell your shell not to touch this string. %d means digits from 1 to whatever the last file is (if you would want them to be 0-padded this would look like %000d to have maximum of three naughts in front).
VLC has then opened and ran my file just fine.

midi to ogg - pipeline distortion

I am trying to convert midi files to ogg or mp3. Eventually this will happen on a linux webserver but currently I am using a Windows 7 machine. I am using timidity to convert the midi to wav and then either sox or ffmpeg to convert the wav to ogg/mp3.
When I use an intermediate file the process works fine (in the first line below timidity creates file.wav)
timidity.exe file.mid -Ow
sox.exe file.wav file.ogg
However, when I try to pipe the timidity output into sox (as below), the resulting file ogg is horribly distorted
timidity.exe file.mid -Ow -o - | sox.exe -t wav - file.ogg
and I get a warning
sox.exe WARN wav: Premature EOF on .wav input file
I also get the same distortion problem when I replace sox with ffmpeg (and the appropriate command line options), or when I replace ogg with mp3 as the output format.
So what am I doing wrong?
Thanks,
Chris
Regarding the warning itself, you're doing nothing wrong. You may also see a warning from timidity that reads something like
Warning: -: Illegal seek: Can't make valid header
What's happening there is explained in the timidity manual page:
If output is directed to a non-seekable file, or if TiMidity++ is interrupted before closing the file, the file header will contain 0xffffffff in the RIFF and data block length fields.
Note that RIFF is the encoding format commonly called by its file extension, .wav. When timidity writes a RIFF file, it doesn't know how long the file will be, so it writes some placeholder junk in the header and moves on to writing the data. When it finishes with the data, it knows how long the file is, so it goes back to the beginning of the file and writes over that junk in the header. When you write to a pipe, it has no way to go back and rewrite anything: the downstream program has to handle the placeholder junk. Also from the timidity manual page:
The popular sound conversion utility sox is able to read such malformed files, so you can pipe data directly to sox for on-the-fly conversion to other formats.
Thus, the message you mentioned. Sox is informing you that the chef prepared the file wrong BUT SOX IS HAPPY TO EAT IT ANYWAY BECAUSE SOX IS NOT PICKY. Sox is apparently passive-aggressive. Who knew?
You can ignore those warning messages, because now they are telling you something you already know. Or, you can use a raw format and explicitly tell timidity and sox how to play well with one another:
timidity file.midi -Or1Ssl -s44.1 -o- | sox -t raw -b 16 -e signed -r 44.1k -c 2 - file.ogg
As for the distortion, that may be caused in part by quirks in the audio libraries on the Windows system. I note that the pipeline in the question, sans .exe extensions, produces output with no notable distortion on a linux system. Using a well-defined raw format in the pipeline may also help with that issue.
Note that for Ogg output, you can now get that directly from timidity:
timidity file.midi -o file.ogg -Ov

Mix audio files with an offset(at particular points) using SOX

I have two audio files one is 10 secs long and other is 17 secs long, I want to mix the files together so that the 17 sec file starts playing from the start, while the 10 sec file will start after 7 seconds into the 17seconds file.
How can I do this?
I followed this link, I also tried other commands mentioned in Sox FAQ, question number 7, but I am unable to mix two files by providing an offset, I also tried the command in command line and the error is same.
The error which I see is
option ` ' not recognized
and the command I used is
sox -m drums.wav "|sox beats.wav -p pad 1.5" out.wav
Edit: It seems to me that the pipe operator "|" is broken, how do I fix this?
My problem is exactly the same as mentioned in this forum
I think there's an issue with ".
Try
sox -m drums.wav '|sox beats.wav -p pad 1.5' out.wav

Resources