# AUTOGENERATED! DO NOT EDIT! File to edit: ../03b_chunk_one_file.ipynb.

# %% auto 0
__all__ = ['blow_chunks', 'chunk_one_file']

# %% ../03b_chunk_one_file.ipynb 5
import os 
import torch
import torchaudio
from .core import is_silence, load_audio, makedir, get_audio_filenames, normalize_audio, get_dbmax

# %% ../03b_chunk_one_file.ipynb 6
def blow_chunks(
    audio:torch.tensor,  # long audio file to be chunked
    new_filename:str,    # stem of new filename(s) to be output as chunks
    chunk_size:int,      # how big each audio chunk is, in samples
    sr=48000,            # audio sample rate in Hz
    norm='False',      # normalize input audio, based on the max of the absolute value ['global','channel', or anything else for None, e.g. False]
    spacing=0.5,         # fraction of each chunk to advance between hops
    strip=False,    # strip silence: chunks with max power in dB below this value will not be saved to files
    thresh=-70,      # threshold in dB for determining what counts as silence
    debug=False,     # print debugging information 
    ):
    "chunks up the audio and saves them with --{i} on the end of each chunk filename"
    if (debug): print(f"       blow_chunks: audio.shape = {audio.shape}",flush=True)
        
    chunk = torch.zeros(audio.shape[0], chunk_size)
    _, ext = os.path.splitext(new_filename)
    
    if norm in ['global','channel']:  audio = normalize_audio(audio, norm)     

    spacing = 0.5 if spacing == 0 else spacing # handle degenerate case as a request for the defaults
    
    start, i = 0, 0
    while start < audio.shape[-1]:
        out_filename = new_filename.replace(ext, f'--{i}'+ext) 
        end = min(start + chunk_size, audio.shape[-1])
        if end-start < chunk_size:  # needs zero padding on end
            chunk = torch.zeros(audio.shape[0], chunk_size)
        chunk[:,0:end-start] = audio[:,start:end]
        if (not strip) or (not is_silence(chunk, thresh=thresh)):
            torchaudio.save(out_filename, chunk, sr)
        else:
            print(f"Skipping chunk {out_filename} because it's 'silent' (below threhold of {thresh} dB).",flush=True)
        start, i = start + int(spacing * chunk_size), i + 1
    return 

# %% ../03b_chunk_one_file.ipynb 7
def chunk_one_file(
    filenames:list,      # list of filenames from which we'll pick one
    args,                # output of argparse
    file_ind             # index from filenames list to read from
    ):
    "this chunks up one file by setting things up and then calling blow_chunks"
    filename = filenames[file_ind]  # this is actually input_path+/+filename
    output_path, input_paths = args.output_path, args.input_paths
    new_filename = None
    if args.debug: print(f" --- process_one_file: filenames[{file_ind}] = {filename}\n", flush=True)
    
    for ipath in input_paths: # set up the output filename & any folders it needs
        if args.nomix and ('Mix' in ipath) and ('Audio Files' in ipath): return  # this is specific to the BDCT dataset, otherwise ignore
        if ipath in filename:
            last_ipath = ipath.split('/')[-1]           # get the last part of ipath
            clean_filename = filename.replace(ipath,'') # remove all of ipath from the front of filename
            new_filename = f"{output_path}/{last_ipath}/{clean_filename}".replace('//','/') 
            makedir(os.path.dirname(new_filename))      # we might need to make a directory for the output file
            break

    if new_filename is None:
        print(f"ERROR: Something went wrong with name of input file {filename}. Skipping.",flush=True) 
        return 
    
    try:
        if args.debug: print(f"   About to load filenames[{file_ind}] = {filename}\n", flush=True)
        audio = load_audio(filename, sr=args.sr, verbose=args.debug)
        if args.debug: print(f"   We loaded the audio, audio.shape = {audio.shape}\n   Calling blow_chunks...", flush=True)
        blow_chunks(audio, new_filename, args.chunk_size, sr=args.sr, spacing=args.spacing, strip=args.strip, thresh=args.thresh, debug=args.debug)
    except Exception as e: 
        print(f"Error '{e}' while loading {filename} or writing chunks. Skipping.", flush=True)

    if args.debug: print(f" --- File {file_ind}: {filename} completed.\n", flush=True)
    return
