forked from Chiro-Canto/TadaridaTools
Updated zip compression method, and README
This commit is contained in:
parent
f9a0c18120
commit
407a7b0477
@ -1,3 +1,10 @@
|
|||||||
# TadaridaTools
|
# TadaridaTools
|
||||||
|
|
||||||
Set of Tools to perform acoustic analysis and preprocess audio recordings to be sent to Vigie-Chiro plateform.
|
Set of Tools to perform acoustic analysis and preprocess audio recordings to be sent to Vigie-Chiro plateform.
|
||||||
|
|
||||||
|
|
||||||
|
## tadam requirements
|
||||||
|
|
||||||
|
* 7z
|
||||||
|
* python3
|
||||||
|
* python soundfile
|
||||||
|
44
src/tadam.py
44
src/tadam.py
@ -25,7 +25,6 @@ import getopt
|
|||||||
import zipfile
|
import zipfile
|
||||||
|
|
||||||
verbose = False
|
verbose = False
|
||||||
chunk_length = -1
|
|
||||||
|
|
||||||
def usage():
|
def usage():
|
||||||
usage_str = """
|
usage_str = """
|
||||||
@ -40,7 +39,7 @@ def usage():
|
|||||||
License: GNU GPL v3 or later
|
License: GNU GPL v3 or later
|
||||||
|
|
||||||
Requirements:
|
Requirements:
|
||||||
pysoundfile
|
pysoundfile, numpy
|
||||||
|
|
||||||
Usage:
|
Usage:
|
||||||
./tadam.py -i INPUT_FOLDER [ -o OUTPUT_FOLDER ]
|
./tadam.py -i INPUT_FOLDER [ -o OUTPUT_FOLDER ]
|
||||||
@ -56,25 +55,14 @@ def usage():
|
|||||||
-r (--ratio) - Specify samplerate convertion rate
|
-r (--ratio) - Specify samplerate convertion rate
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
tadam -v -i raw -o exp -l 5 -z -p "Car910130-2021-Pass0-Z1-AudioMoth-247AA5015FDF286B-" -r 0.1
|
tadam -v -i raw -o exp -l 5 -z -p "Car910130-2021-Pass1-Z1-AudioMoth_" -r 0.1
|
||||||
"""
|
"""
|
||||||
print(usage_str)
|
print(usage_str)
|
||||||
|
|
||||||
def rate(infile, outfile, rate_ratio):
|
def rate(infile, outfile, rate_ratio):
|
||||||
data, samplerate = sf.read(infile)
|
data, samplerate = sf.read(infile)
|
||||||
new_samplerate = int(samplerate * rate_ratio)
|
new_samplerate = int(samplerate * rate_ratio)
|
||||||
if (chunk_length != -1):
|
sf.write(outfile, data, new_samplerate)
|
||||||
if verbose:
|
|
||||||
print(f"\t Splitting {infile} in {chunk_length}s-long chunks.")
|
|
||||||
sections = int(np.ceil(len(data) / samplerate / chunk_length))
|
|
||||||
for i in range(sections):
|
|
||||||
if verbose:
|
|
||||||
print(f"\t {str(i).zfill(len(str(sections)))}/{sections} \t {outfile}")
|
|
||||||
filename = outfile.replace('.wav', f'-{str(i).zfill(len(str(sections)))}.wav')
|
|
||||||
temp = data[i*samplerate*chunk_length : i*samplerate*chunk_length+samplerate*chunk_length]
|
|
||||||
sf.write(filename, temp, samplerate)
|
|
||||||
else:
|
|
||||||
sf.write(outfile, data, new_samplerate)
|
|
||||||
|
|
||||||
def convert_folder(infolder, outfolder, rate_ratio, prefix):
|
def convert_folder(infolder, outfolder, rate_ratio, prefix):
|
||||||
try:
|
try:
|
||||||
@ -85,17 +73,31 @@ def convert_folder(infolder, outfolder, rate_ratio, prefix):
|
|||||||
n = len(infiles)
|
n = len(infiles)
|
||||||
i = 1
|
i = 1
|
||||||
for infile in infiles:
|
for infile in infiles:
|
||||||
outfile = prefix + infile.replace('.WAV', '.wav').replace('.wav', f'.exp_x{int(1/rate_ratio)}.wav')
|
outfile = prefix + infile.replace('.WAV', '.wav')
|
||||||
if verbose:
|
if verbose:
|
||||||
print(f"{str(i).zfill(len(str(n)))}/{n} Processing {infile} → {outfile}...")
|
print(f"{str(i).zfill(len(str(n)))}/{n} Processing {infile} → {outfile}...")
|
||||||
rate(os.path.join(infolder, infile), os.path.join(outfolder, outfile), rate_ratio)
|
rate(os.path.join(infolder, infile), os.path.join(outfolder, outfile), rate_ratio)
|
||||||
|
i += 1
|
||||||
|
|
||||||
|
def chunk(outfolder, length):
|
||||||
|
for file in os.listdir(outfolder):
|
||||||
|
infile = os.path.join(outfolder, file)
|
||||||
|
data, samplerate = sf.read(infile)
|
||||||
|
if verbose:
|
||||||
|
print(f"\t Splitting {infile} in {length}s-long chunks.")
|
||||||
|
sections = int(np.ceil(len(data) / samplerate / length))
|
||||||
|
for i in range(sections):
|
||||||
|
if verbose:
|
||||||
|
print(f"\t {str(i).zfill(len(str(sections)))}/{sections} \t {infile}")
|
||||||
|
filename = infile.replace('.wav', f'_{str(i).zfill(3)}.wav')
|
||||||
|
temp = data[i*samplerate*length : i*samplerate*length+samplerate*length]
|
||||||
|
sf.write(filename, temp, samplerate)
|
||||||
|
os.remove(infile)
|
||||||
|
|
||||||
def zip_folder(outfolder):
|
def zip_folder(outfolder):
|
||||||
if verbose:
|
if verbose:
|
||||||
print("Compressing .zip archive...")
|
print("Compressing .zip archive...")
|
||||||
with zipfile.ZipFile(f"{outfolder}.zip", 'w') as f:
|
os.system('7z -v700m a output.zip exp')
|
||||||
for file in os.listdir(outfolder):
|
|
||||||
f.write(os.path.join(outfolder, file))
|
|
||||||
if verbose:
|
if verbose:
|
||||||
print("Archive compressed.")
|
print("Archive compressed.")
|
||||||
|
|
||||||
@ -112,6 +114,7 @@ def main():
|
|||||||
outfolder = "exp"
|
outfolder = "exp"
|
||||||
compress = False
|
compress = False
|
||||||
prefix = ""
|
prefix = ""
|
||||||
|
chunk_length = -1
|
||||||
|
|
||||||
for o, a in opts:
|
for o, a in opts:
|
||||||
if o in ("-v", "--verbose"):
|
if o in ("-v", "--verbose"):
|
||||||
@ -126,7 +129,6 @@ def main():
|
|||||||
elif o in ("-r", "--ratio"):
|
elif o in ("-r", "--ratio"):
|
||||||
rate_ratio = float(a)
|
rate_ratio = float(a)
|
||||||
elif o in ("-l", "--length"):
|
elif o in ("-l", "--length"):
|
||||||
global chunk_length
|
|
||||||
chunk_length = int(a)
|
chunk_length = int(a)
|
||||||
elif o in ("-z", "--zip"):
|
elif o in ("-z", "--zip"):
|
||||||
compress = True
|
compress = True
|
||||||
@ -136,6 +138,8 @@ def main():
|
|||||||
assert False, "unhandled option"
|
assert False, "unhandled option"
|
||||||
|
|
||||||
convert_folder(infolder, outfolder, rate_ratio, prefix)
|
convert_folder(infolder, outfolder, rate_ratio, prefix)
|
||||||
|
if chunk_length != -1:
|
||||||
|
chunk(outfolder, chunk_length)
|
||||||
if compress:
|
if compress:
|
||||||
zip_folder(outfolder)
|
zip_folder(outfolder)
|
||||||
if verbose:
|
if verbose:
|
||||||
|
Loading…
Reference in New Issue
Block a user