Loop Over a List Containing Path to Sound Files

Trying to iterate through .wav files in a directory (Python)

It seems that you're just not running your code in the wav directory. listdir just return the filename, not the whole path, you need to join with the directory

p1 = AudioSegment.from_wav(os.path.join(directory, filename))

Python: Create a list of directories containing audio files

from glob import glob
list_subfolders_with_paths = glob('path/*.mp3')

Replace mp3 with audio files extensions and * is for every mp3 file in path.

JAVA - iterate through a folder of audio files, concatenating another audio file to each one

The error

AudioInputStream clip1 = AudioSystem.getAudioInputStream(new File(f.getName()));

This tries to create a file with the given file name, and looks for it in the current directory.

You should be using File.getAbsolutePath() to get the full absolute path to the file

AudioInputStream clip1 = AudioSystem.getAudioInputStream(new File(f.getAbsolutePath()));

or more simply

AudioInputStream clip1 = AudioSystem.getAudioInputStream(f);

Same problem with wavFile2

I suspect you will have the same issue with the second file:

AudioInputStream clip2 = AudioSystem.getAudioInputStream(new File(wavFile2));

You will need to provide an absolute path here too. If it also is in the audDir then do

File wavFile2 = new File(audDir.getAbsolutePath() + "/silence_2sec.wav");
AudioInputStream clip2 = AudioSystem.getAudioInputStream(wavFile2);

Iterating over .wav files in subdirectories of parent directory

Edit: If you want an example for glob (more sane), here it is:

from pathlib import Path

# The pattern "**" means all subdirectories recursively,
# with "*.wav" meaning all files with any name ending in ".wav".
for file in Path(data_path).glob("**/*.wav"):
if not file.is_file(): # Skip directories
continue

with open(file, "w") as f:
# do stuff

For more info see Path.glob() on the documentation. Glob patterns are a useful thing to know.

Previous answer:

Try using either glob or os.walk(). Here is an example for os.walk().

from os import walk, path

# Recursively walk the directory data_path
for root, _, files in walk(data_path):
# files is a list of files in the current root, so iterate them
for file in files:
# Skip the file if it is not *.wav
if not file.endswith(".wav"):
continue

# os.path.join() will create the path for the file
file = path.join(root, files)
# Do what you need with the file
# You can also use block context to open the files like this
with open(file, "w") as f: # "w" means permission to write. If reading, use "r"
# Do stuff

Note that you may be confused about what open() does. It opens a file for reading, writing, and appending. Directories are not files, and therefore cannot be opened.

I suggest that you Google for documentation and do more reading about the functions used. The documentation will help more than I can.

Another good answer explaining in more detail can be seen here.

Loop of function for taking multiple audio files from a directory

You can get all files of a directory and subdirectory with os.walk, which I have included in the get_file_paths() in the code below, here is an example:

import speech_recognition as sr
import csv
import os

DIRNAME = r'c:\path\to\directory'
OUTPUTFILE = r'c:\path\to\outputfiledir\outputfile.csv'

def get_file_paths(dirname):
file_paths = []
for root, directories, files in os.walk(dirname):
for filename in files:
filepath = os.path.join(root, filename)
file_paths.append(filepath)
return file_paths

def process_file(file):
r = sr.Recognizer()
a = ''
with sr.AudioFile(file) as source:
audio = r.record(source)
try:
a = r.recognize_google(audio)
except sr.UnknownValueError:
a = "Google Speech Recognition could not understand audio"
except sr.RequestError as e:
a = "Could not request results from Google Speech Recognition service; {0}".format(e)
return a

def main():
files = get_file_paths(DIRNAME) # get all file-paths of all files in dirname and subdirectories
for file in files: # execute for each file
(filepath, ext) = os.path.splitext(file) # get the file extension
file_name = os.path.basename(file) # get the basename for writing to output file
if ext == '.wav': # only interested if extension is '.wav'
a = process_file(file) # result is returned to a
with open(OUTPUTFILE, 'a') as f: # write results to file
writer = csv.writer(f)
writer.writerow(['file_name','google'])
writer.writerow([file_name, a])

if __name__ == '__main__':
main()

If you want to do multiple recognizers, something like this could work. Please note this is an untested example:

import speech_recognition as sr
import csv
import os

DIRNAME = r'c:\path\to\directory'
OUTPUTFILE = r'c:\path\to\outputfiledir\outputfile.csv'

def get_file_paths(dirname):
file_paths = []
for root, directories, files in os.walk(dirname):
for filename in files:
filepath = os.path.join(root, filename)
file_paths.append(filepath)
return file_paths

def recog_multiple(file):
r = sr.Recognizer()
r_types = ['recognize_google', 'recognize_sphinx']
results = []
for r_type in r_types:
result = ''
with sr.AudioFile(file) as source:
audio = r.record(source)
try:
result = r_type + ': ' + str(getattr(r, r_type)(audio))
except sr.UnknownValueError:
result = r_type + ': Speech Recognition could not understand audio'
except sr.RequestError as e:
result = r_type + ': Could not request results from Speech Recognition service; {0}'.format(e)
results.append(result)
return results

def main():
files = get_file_paths(DIRNAME) # get all file-paths of all files in dirname and subdirectories
for file in files: # execute for each file
(filepath, ext) = os.path.splitext(file) # get the file extension
file_name = os.path.basename(file) # get the basename for writing to output file
if ext == '.wav': # only interested if extension is '.wav'
a = recog_multiple(file) # result is returned to a
with open(OUTPUTFILE, 'a') as f: # write results to file
writer = csv.writer(f)
writer.writerow(['file_name','results'])
writer.writerow([file_name, a])

if __name__ == '__main__':
main()

bash: best practice to iterate over directory content until condition matches

Probably the safest way would be to iterate over the glob results directly, so you aren't vulnerable to the filenames containing special characters:

for path in "$1"/*; do
if file -b -- "$path" | grep -qi audio; then
printf 'Found an audio file %s\n' "$path"
process_audio_dir
exit
fi
done
# since we didn't exit above, most be no audio files
printf "Didn't find any audio files\n"
process_noaudio

Alternately, if you don't want to exit there, you could set a flag indicating that you found it and check that after the loop, and just use a break inside the if to exit the loop once you've found one.

The reason yours is applying grep to the output of all the file results, is that the glob expands first so you then run the command, for example

file -b dir/file1 dir/file2 dir/file3 ...

then the output of that command will be fed to grep My solution puts the glob on the "outside" of the command, so we'll just run it on each file individually. Of course, there's more overhead with launching file lots of times, so it's not obvious to me right away which is going to be more efficient. It'll probably depend on how many files there are, how far down the list the first audio file usually is and stuff like that.

As has been mentioned in the comments, it's dangerous to iterate over the printed filename results from find or ls, since those results would be subject to word splitting and potentially globbing depending on how exactly you do it. Using the for loop above is the recommended way to do it generally. For more see Don't Parse ls

How to iterate files in directory with for loop in Bash

The for-loop is basically sound. However, if the directory is empty, the loop will be executed once, with the variable file containing the literal text /var/spool/bandit24/*.

The stat message is not from the for-loop, but from one of the commands in the loop.

The correct way would be to test if the directory is empty before you continue. You could put something like

if [ $(find . -type f | wc -l) -eq 0 ] ; then
echo "Nothing to do"
exit 0
fi

right after the cd.

Some other comments on your script.

  • If you do a cd in the script, you don't need to specify the full path anymore.
  • Your quoting is not really consistent. That may not be a problem if your file names never contain spaces or strange characters, but I would, for example timeout -s 9 60 "./$file" and rm -f "./file"
  • /var/spool/bandit/* will never contain . or .., so that test is useless.
  • You could also replace the test with if [ -f "$file" ] ; then


Related Topics



Leave a reply



Submit