Change huge amount of data from NIST to RIFF wav file - audio

So, I am writing a speech recognition program. To do that I downloaded 400MB of data from TIMIT. When I inteded to read the wav files (I tried two libraries) as follow:
import scipy.io.wavfile as wavfile
import wave
(fs, x) = wavfile.read('../data/TIMIT/TRAIN/DR1/FCJF0/SA1.WAV')
w = wave.open('../data/TIMIT/TRAIN/DR1/FCJF0/SA1.WAV')
In both cases they have the problem that the wav file format says 'NIST' and it must be in 'RIFF' format. (Something about sph also I readed but the nist file I donwloaded are .wav, not .sph).
I downloaded then SOX from http://sox.sourceforge.net/
I added the path correctly to my enviromental variables so that my cmd recognize sox. But I can't really find how to use it correctly.
What I need now is a script or something to make sox change EVERY wav file format from NIST to RIFF under certain folder and subfolder.
EDIT:
in reading a WAV file from TIMIT database in python I found a response that worked for me...
Running sph2pipe -f wav input.wav output.wav
What I need is a script or something that searches under a folder, all subfolders that contain a .wav file to apply that line of code.

Since forfiles is a Windows command, here is a solution for unix.
Just cd to the upper folder and type:
find . -name '*.WAV' | parallel -P20 sox {} '{.}.wav'
You need to have installed parallel and sox though, but for Mac you can get both via brew install. Hope this helps.

Ok, I got it finally. Go to the upper folder and run this code:
forfiles /s /m *.wav /c "cmd /c sph2pipe -f wav #file #fnameRIFF.wav"
This code searches for every file and make it readble for the python libs. Hope it helps!

Related

Chopping audio files with ffmpeg get None duration python 3

I have a long list of audio files, and some of them are longer than an hour. I am using Python 3.6, Jupyter notebook by connecting to a remote machine and using TinyTag library to get a duration of audio. Ffmpeg version is 2.8.14-0ubuntu0.16.04.1.
My code below goes over the files and if a file is longer than an hour, it splits the file into one-hour long pieces, and a leftover piece less than an hour, and copies the pieces as fname_0, fname_1,fname_2, etc. Before chopped, each file is .m4a but during chopping, they are converted to a .wav file. However, after this chopping process, when reading the duration of pieces, I realized that all the pieces have 'None' duration. Something must be wrong in the command line but I can`t see what that is. Thanks in advance.
# fpaths is the list of filepaths
for i in range(0,len(fpaths)):
fpath=fpaths[i]
fname=os.path.basename(fpath)
fname0=os.path.splitext(fname)[0] #name without extension
tag = TinyTag.get(fname)
if tag.duration > 3600:
cmd2 = "ffmpeg -i %s -f segment -segment_time 3600 -c copy %s" %(fpath, fname0) + "_%d.wav"
os.system(cmd2)
os.remove(fpath)
When I change to the extension from .wav to .m4a in the cmd2 command line, it works. Writing here just in case if someone has the same problem.

SoX Not Reading Wav

I've got a large (5Gb) WAV 64 file that I'm trying to analyse with SoX. On doing;
sox /file/ -n stats
it tells me;
sox FAIL formats: can't open input file '/file/': WAVE: RIFF header not found
On attempting to specify;
sox /file/ -t w64 -n stats
it says;
sox WARN sox: ignoring `-t w64'.
and proceeds to throw the same error as before. This file is W64. How do I convince SoX to accept it?
Looks like ffmpeg can handle wav64 files
Have you tried to create your own tiny wav64 file and see if you can read that ?
Looks like wav64 is targeted for multichannel audio is that your use case ? WAV format itself is very simple and lends itself to allowing people to write two pages of code to read any wav file ... if you exhaust all other options and your life depended on getting your file read, reading the ISO spec or similar on wav64 format then writing your own reader is an option.
Can you share how your wav64 file was created ? Maybe one of us can replicate its creation and battle how to read it back
If its not full of massive multi-channel audio is getting it converted to normal wav an option ?
Maybe, your wave64 file is invalid. A valid one should contain a riff header.
You've added -t w64 flag after the filename. That's why it's ignored.
# This would work! [CHECKED]
# If your file is valid!
sox -t w64 in_file -n stats

Mix .L and .R files into a stereo file using SOX in bulk

I have a folder full of WAV files with separate L and R channels. I've been using SOX for some things like changing the sample rate of the audio files inside a specific folder using this code:
for file in *.wav; do sox $file -r 44100 -b 24 converted/$(basename $file) -V; done
For example, I have these two files that I want to merge:
- CLOSE_1_02.L.wav
- CLOSE_1_02.R.wav
I would like to merge them in a stereo file (L in the left channel and R in the right channel) with the name: "CLOSE_1_02.wav". Can anybody help me?
Thanks.
from link:
sox -M input.l.wav input.r.wav output.wav
will merge input.l.wav and input.r.wav into output.wav.
I'm sorry, but the answer (1) is wrong. The questioner wants a two-channel file with one sound file in the left channel, and the other in the right channel. I tried the command given, and it produces a 1-channel output.wav with both input files mixed into a single channel.

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

An efficient way to detect corrupted png files?

I've written a program to process a bunch of png files that are generated by a seperate process. The capture mostly works, however there are times when the process dies and is restarting which leaves a corrupted image. I have no way to detect when the process dies or which file it dies one (there are ~3000 png files).
Is there a good way to check for a corrupted png file?
I know this is a question from 2010, but I think this is a better solution: pngcheck.
Since you're on a Linux system you probably already have Python installed.
An easy way would be to try loading and verifying the files with PIL (Python Imaging Library) (you'd need to install that first).
from PIL import Image
v_image = Image.open(file)
v_image.verify()
(taken verbatim from my own answer in this thread)
A different possible solution would be to slightly change how your processor processes the files: Have it always create a file named temp.png (for example), and then rename it to the "correct" name once it's done. That way, you know if there is a file named temp.png around, then the process got interrupted, whereas if there is no such file, then everything is good.
(A variant naming scheme would be to do what Firefox's downloader does -- append .partial to the real filename to get the temporary name.)
Kind of a hack, but works
If you are running on linux or something like you might have the "convert" command
$ convert --help
Version: ImageMagick 5.5.6 04/01/03 Q16 http://www.imagemagick.org
Copyright: Copyright (C) 2003 ImageMagick Studio LLC
Usage: convert [options ...] file [ [options ...] file ...] [options ...] file
If you make an invalid png, and then try to convert, you'll get an error:
$ date> foo.png
$ convert foo.png foo.gif
convert: NotAPNGImageFile (foo.png).
Find all non-PNG files:
find . -type f -print0 | xargs -0 file --mime | grep -vF image/png
Find all corrupted PNG files:
find . -type f -print0 | xargs -0 -P0 sh -c 'magick identify +ping "$#" > /dev/null' sh
file command only checks magic number. Having the PNG magic number doesn't mean it is a well formed PNG file.
magick identify is a tool from ImageMagick. By default, it only checks headers of the file for better performance. Here we use +ping to disable the feature and make identify read the whole file.

Resources